[ruby-on-rails] 찾기 대 find_by 대 어디

나는 레일을 처음 사용합니다. 레코드를 찾는 방법이 많이 있다는 것을 알았습니다.

  1. find_by_<columnname>(<columnvalue>)
  2. find(:first, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>).first

그리고 모두 정확히 동일한 SQL을 생성하는 것처럼 보입니다. 또한 여러 레코드를 찾는 경우에도 마찬가지입니다.

  1. find_all_by_<columnname>(<columnvalue>)
  2. find(:all, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>)

어떤 규칙을 사용할 것인지에 대한 경험 규칙이나 추천 규칙이 있습니까?



답변

자신의 요구에 가장 잘 맞는 것을 사용하십시오.

find방법은 일반적으로 ID별로 행을 검색하는 데 사용됩니다.

Model.find(1)

제공 find한 속성으로 항목을 찾을 수없는 경우 예외가 발생합니다. where예외가 발생하지 않도록 하려면 (아래 설명에 따라 속성을 찾을 수없는 경우 빈 배열을 반환 함)을 사용하십시오.

다른 용도 find는 일반적으로 다음과 같은 것으로 대체됩니다.

Model.all
Model.first

find_by열 내에서 정보를 검색 할 때 도우미로 사용되며 명명 규칙을 사용하여 이러한 정보에 매핑됩니다. 예를 들어, name데이터베이스에 이름이 지정된 열이있는 경우 다음 구문을 사용합니다.

Model.find_by(name: "Bob")

.where 는 일반적인 도우미가하지 않을 때 좀 더 복잡한 논리를 사용할 수있게 해주는 조건입니다. 조건에 맞는 항목의 배열 (또는 빈 배열)을 반환합니다.


답변

여기서 ActiveRecord :: Relation을 반환합니다.

이제 find_by 구현을 살펴보십시오.

def find_by
  where(*args).take
end

보시다시피 find_bywhere 와 동일 하지만 하나의 레코드 만 반환합니다. 이 방법은 (1 개) 기록을 받고 사용해야합니다 경우 일부 조건과 모든 레코드를 얻기 위해 사용되어야한다.


답변

Model.find

1- 매개 변수 : 찾을 개체의 ID입니다.

2- 발견 된 경우 : 오브젝트를 리턴합니다 (한 오브젝트 만).

3- 찾을 수없는 경우 : ActiveRecord::RecordNotFound예외 가 발생합니다.

Model.find_by

1-매개 변수 : 키 / 값

예:

User.find_by name: 'John', email: 'john@doe.com'

2- 발견 된 경우 : 오브젝트를 리턴합니다.

3- 찾을 수없는 경우 :을 반환합니다 nil.

참고 :ActiveRecord::RecordNotFound 사용을 늘리려면find_by!

Model.where

1- 매개 변수 : find_by

2- 발견 된 경우 : ActiveRecord::Relation매개 변수와 일치하는 하나 이상의 레코드를 포함하여 리턴합니다 .

3- 찾을 수없는 경우 : Empty를 반환합니다 ActiveRecord::Relation.


답변

사이에 차이가 find하고 find_by있다는 점에서 find찾을 수없는 경우, 반면에 오류가 반환됩니다 find_by널 (null)을 반환합니다은.

find_by email: "haha"반대로 와 같은 방법이 있다면 읽기가 더 쉽습니다 .where(email: some_params).first.


답변

Rails 4부터 다음을 수행 할 수 있습니다.

User.find_by(name: 'Bob')

이는 find_by_nameRails 3 과 동일 합니다.

사용 #where하는 경우 #find#find_by충분하지 않습니다.


답변

허용 대답은 일반적으로 모든 것을 커버,하지만 난 당신이 업데이트와 같은 방법으로 모델 일을 계획하고, 당신은 (그 하나의 레코드 검색하는 넣다 뭔가를 추가하고 싶습니다 id, 그리고 당신이 모르는를) find_by입니다 레코드를 검색하고 배열에 넣지 않기 때문에 갈 길

irb(main):037:0> @kit = Kit.find_by(number: "3456")
  Kit Load (0.9ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =
 '3456' LIMIT 1
=> #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56",   
updated_at: "2015-05-12 06:10:56", job_id: nil>

irb(main):038:0> @kit.update(job_id: 2)
(0.2ms)  BEGIN Kit Exists (0.4ms)  SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE  "kits"."id" =
1  [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]]
(0.6ms)  COMMIT => true

그러나 사용 where하면 직접 업데이트 할 수 없습니다

irb(main):039:0> @kit = Kit.where(number: "3456")
Kit Load (1.2ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =
'3456' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456", 
created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58",
job_id: 2>]>

irb(main):040:0> @kit.update(job_id: 3)
ArgumentError: wrong number of arguments (1 for 2)

이러한 경우 다음과 같이 지정해야합니다

irb(main):043:0> @kit[0].update(job_id: 3)
(0.2ms)  BEGIN Kit Exists (0.6ms)  SELECT 1 AS one FROM "kits" WHERE
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms)
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1
[["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]]
(0.5ms)  COMMIT => true


답변

허용 된 답변 외에 다음도 유효합니다.

Model.find()ID 배열을 허용하고 일치하는 모든 레코드를 반환합니다.
Model.find_by_id(123)또한 배열을 수락하지만 배열에있는 첫 번째 id 값만 처리합니다.

Model.find([1,2,3])
Model.find_by_id([1,2,3])