[ruby-on-rails] 찾기 대 find_by 대 어디
나는 레일을 처음 사용합니다. 레코드를 찾는 방법이 많이 있다는 것을 알았습니다.
find_by_<columnname>(<columnvalue>)
find(:first, :conditions => { <columnname> => <columnvalue> }
where(<columnname> => <columnvalue>).first
그리고 모두 정확히 동일한 SQL을 생성하는 것처럼 보입니다. 또한 여러 레코드를 찾는 경우에도 마찬가지입니다.
find_all_by_<columnname>(<columnvalue>)
find(:all, :conditions => { <columnname> => <columnvalue> }
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_by 는 where 와 동일 하지만 하나의 레코드 만 반환합니다. 이 방법은 (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_name
Rails 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])