--Do not understand where or pluck return values and share your jammed experience
――With the meaning of remorse for abusing ActiveRecord, saying "You can go with .id
"
-~~ where and pluck return values are arrays ~~ → pluck is returned as an array --where returns ActiveRecord :: Relation * Addition 20/11/10 --Understand how to use ActiveRecord method chains
・ Ruby 2.6.5 ・ Rails 6.0.3 -Use devise (user model)
rooms table: manage rooms to DM user_rooms table: Manage user and room combinations
The image is the user_rooms table.
What you want to do
I want to get the user information of the DM partner (id = 10)
Conditions
The room to DM is room_id: 2
I (current_user) is user_id: 15
I tried to realize it with the code below
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
Line 3: Define @room (id: 2) with two users participating.
Line 4: Get the @room and user combination with @ room.user_rooms
. (At this point, the records are narrowed down to two.) In addition, where.not (user_id: current_user.id)
narrows down to the record that does not include you.
5th line: Of the records obtained in the 4th line, we are trying to get the user_id.
However, on the 4th line, the following error occurs.
[*] pry(main)> current_user_room.user_id
#result
NoMethodError: undefined method `user_id' for #<UserRoom::ActiveRecord_AssociationRelation:0x00007fbef39437e8>
???
For the time being, I will output current_user_room
[**] pry(main)> current_user_room
#result
=> [#<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>]
Why can't I? Try to get it with find
using id = 2
[**] pry(main)> user_room1 = UserRoom.find(2)
#result
=> #<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>
At first, the result looked the same, but if you look closely, the current_user_room
has[]
and is in an array ~~. ~~ → Addition
The current_user_room
was fetched by the ** where
method **.
~~ You can't get it by applying a method chain to an array. Of course, the where
method takes a set of data. ~~
By the way, I tried to get the user_id
with the pluck
method, but the result was the same.
~~ It seems to be solved if you pick it up from the array. ~~
So [Rails Guide](https://railsguides.jp/active_record_querying.html#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%83%81 % E3% 82% A7% E3% 82% A4% E3% 83% B3% E3% 82% 92% E7% 90% 86% E8% A7% A3% E3% 81% 99% E3% 82% 8B) Looking at it, it seems that the take
method can be used. I know I want to get one.
The take method takes one record. It does not specify which records are retrieved.
rooms_controller.rb
#Original code
current_user_room = @room.user_rooms.where.not(user_id: current_user.id)
#Corresponding code(At the end.Add take)
current_user_room = @room.user_rooms.where.not(user_id: current_user.id).take
[0]
to get the first array in the end.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 #.Add take
user_id = current_user_room.user_id
@user = User.find(user_id)
@messages = @room.messages.includes(:user)
@message = Message.new
end
end
It turns out that where
returns an instance of ActiveRecord :: Relation
, not an array.
# (where) current_user_Check room class
pry(main)> current_user_room.class
=> UserRoom::ActiveRecord_AssociationRelation
# (find) user_Also check room1
pry(main)> user_room.class
=> UserRoom(id: integer, user_id: integer, room_id: integer, created_at: datetime, updated_at: datetime)
I'm still not familiar with it, so I'll take a closer look at ActiveRecord
and ActiveRecord :: Relation
.
For the time being, we have taken measures that can be taken in the current situation, but if we review it from the ground up, it may not even be necessary to describe this in the first place. I want to fix it as soon as I notice it.
However, this time, it was a good study to be able to touch the behavior of where
.
I would like to improve it further, so I would appreciate it if you could point out any deficiencies or other methods.
Rails Guide The difference between find and where in ActiveRecord. → I was very helpful in the postscript.
Recommended Posts