[Rails] where의 반환값에 대한 이야기를 주의하세요.
개시하다
왜 썼어요?
.id
되겠지", 액티브 레코드 남용에 대한 반성의 뜻결론
where 또는 pluck의 반환값은 수조→pluck은 수조로 반환
전제 조건
컨디션
・Rubby 2.6.5
・Rails6.0.3
• devise(user 모델) 사용
ER 그림
rooms 테이블:DM 룸 관리
user_rooms 테이블:user와 room의 조합을 관리합니다
하고 싶은 일
그림은userrooms 책상입니다.
<하고 싶은 일>
DM 객체(id=10)에 대한 사용자 정보를 얻으려고 합니다.
< 조건 >
DM의 룸
room_id: 2
자신(current user)은 user_id: 15
이벤트
다음 코드로 실현하려고 시도합니다
rooms_controller.rb
class RoomsController < ApplicationController
def show
@room = Room.find(params[:id])
current_user_room = @room.user_rooms.where.not(user_id: current_user.id)
user_id = current_user_room.user_id
@user = User.find(user_id)
end
end
세 번째 줄: 두 사용자가 참가한 것을 정의합니다@room(id:2).4행:
@room.user_rooms
에서 @room와 사용자의 조합을 얻는다.(이때 기록은 두 개로 압축됩니다.)그리고 where.not(user_id: current_user.id)
에서 기록을 자신을 포함하지 않는 기록으로 축소한다.다섯 번째 줄: 네 번째 줄에서 얻은 기록 중,userid를 얻으려고 합니다.
단, 4 줄은 다음과 같은 오류가 발생합니다.
[*] pry(main)> current_user_room.user_id
# 結果
NoMethodError: undefined method `user_id' for #<UserRoom::ActiveRecord_AssociationRelation:0x00007fbef39437e8>
???한마디로 출력
current_user_room
[**] pry(main)> current_user_room
# 結果
=> [#<UserRoom:0x00007fbeefb36518
id: 2,
user_id: 10,
room_id: 2,
created_at: Sat, 07 Nov 2020 04:00:28 UTC +00:00,
updated_at: Sat, 07 Nov 2020 04:00:28 UTC +00:00>]
왜 못하지?id=2find
를 사용하여 획득[**] pry(main)> user_room1 = UserRoom.find(2)
# 結果
=> #<UserRoom:0x00007fbeec46c960
id: 2,
user_id: 10,
room_id: 2,
created_at: Sat, 07 Nov 2020 04:00:28 UTC +00:00,
updated_at: Sat, 07 Nov 2020 04:00:28 UTC +00:00>
처음엔 같은 결과로 보였는데 자세히 보면current_user_room
띠[]
의 배열이었다.→ 추기 current_user_room
의 사용자는 where
방법을 통해 얻었다.배열용 방법을 검사해도 찾을 수 없다.
where
방법은 데이터 그룹을 추출하는 것이기 때문에 당연합니다.그나저나
pluck
방법으로 얻고 싶었지만user_id
결과는 마찬가지였다.해결책
배열에서 주우면 해결할 수 있을 거예요.
따라서Rails 가이드보면
take
방법을사용할 수 있을 것 같다.얻고 싶은 게 하나라는 걸 알고 있으니까.take 방법으로 기록을 꺼냅니다.추출할 기록을 지정하지 않았습니다.
rooms_controller.rb
# 元のコード
current_user_room = @room.user_rooms.where.not(user_id: current_user.id)
# 対応コード(末尾に.takeを追加)
current_user_room = @room.user_rooms.where.not(user_id: current_user.id).take
※ 또는 끝에 배열을 추가한 첫 번째[0]
도 취소할 수 있습니다.수정된 코드
rooms_controller.rb
class RoomsController < ApplicationController
def show
@room = Room.find(params[:id])
current_user_room = @room.user_rooms.where.not(user_id: current_user.id).take #.takeを追加
user_id = current_user_room.user_id
@user = User.find(user_id)
@messages = @room.messages.includes(:user)
@message = Message.new
end
end
추기
where
가 되돌아오는 것은 수조가 아니라 ActiveRecord::Relation
의 실례이다.# (where) current_user_room のクラスを確認
pry(main)> current_user_room.class
=> UserRoom::ActiveRecord_AssociationRelation
# (find) user_room1 の方も確認
pry(main)> user_room.class
=> UserRoom(id: integer, user_id: integer, room_id: integer, created_at: datetime, updated_at: datetime)
이해가 아직 얕기 때문에ActiveRecord
ActiveRecord::Relation
잘 조사하고 싶어요.끝말
당분간 지금 대응할 수 있는 대책을 세웠는데 근본적으로 재검토하면 이 기술이 필요없을지도 모른다.눈치채면 고치고 싶어요.
하지만 이번에
where
행동에 닿아 많은 것을 배웠다.수준을 높이고 싶습니다. 만약 완비되지 않거나 다른 방법이 있다면 지적해 주십시오.
참고 자료
Rails 가이드
ActiveRecord의find와where의 차이점→추기 시 참고
Reference
이 문제에 관하여([Rails] where의 반환값에 대한 이야기를 주의하세요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/daiki-mrt/items/88d8a15f11633d201845텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)