[RUBY] [Rails] Talk about paying attention to the return value of where

Introduction

Why i wrote

--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 "

Conclusion

-~~ 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

Premise

environment

・ Ruby 2.6.5 ・ Rails 6.0.3 -Use devise (user model)

ER diagram

スクリーンショット 2020-11-08 18.04.11.png

rooms table: manage rooms to DM user_rooms table: Manage user and room combinations

Thing you want to do

スクリーンショット 2020-11-08 16.44.04.png 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

Event

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.

solution

~~ 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

Modified code

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

Postscript

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.

in conclusion

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.

Reference material

Rails Guide The difference between find and where in ActiveRecord. → I was very helpful in the postscript.

Recommended Posts

[Rails] Talk about paying attention to the return value of where
[Rails] Button to return to the top of the page
9 Corresponds to the return value
about the where method (rails)
[Rails] Where to be careful in the description of validation
[Rails] Read the RSS of the site and return the contents to the front
The process of introducing Vuetify to Rails
[Rails] About the error when displaying the screen due to the autofocus of the form
Pay attention to the boundary check of the input value when using the float type
About the case where "Docker" freeter tried to put Docker in the existing Rails application
[Java] How to get the maximum value of HashMap
[Rails] How to change the column name of the table
Install multiple submit buttons in Rails View to get the value of the pressed button
Pass arguments to the method and receive the result of the operation as a return value
[Rails] How to get the contents of strong parameters
I want to return the scroll position of UITableView!
How to specify an array in the return value / argument of the method in the CORBA IDL file
A note about the seed function of Ruby on Rails
How to change the setting value of Springboot Hikari CP
Let's summarize how to extend the expiration date of Rails
[Rails] How to display the list of posts by category
About the handling of Null
About the description of Docker-compose.yml
Let's talk about the passing experience of Java SE 8 Programmer II
[Rails] How to get the URL of the transition source and redirect
How to display 0 on the left side of the standard input value
The return specification of compareTo can afford without going to the reference
[Rails / Heroku / MySQL] How to reset the DB of Rails application on Heroku
[Rails] How to omit the display of the character string of the link_to method
[Rails] How to change the page title of the browser for each page
[Rails] About Uglifier :: Error: Unexpected token: at the time of deployment
I want to change the value of Attribute in Selenium of Ruby
How to increment the value of Map in one line in Java
About the behavior of ruby Hash # ==
About the basics of Android development
[Rails] About the Punk List function
[Rails] Check the contents of the object
About the symbol <%%> in Rails erb
Explanation of the order of rails routes
[Rails] About implementation of like function
Check the migration status of rails
About the role of the initialize method
Think about the 7 rules of Optional
How to return Rails API mode to Rails
Summary about the introduction of Device
About the log level of java.util.logging.Logger
How to output the sum of any three numbers, excluding the same value
[Rails] I learned about migration files! (Adding a column to the table)
Talk about the merits of database bind variables (② Merit: Prevention of SQL injection)
How to return a value from Model to Controller using the [Swift5] protocol
How to decorate the radio button of rails6 form_with (helper) with CSS
Procedure to make the value of the property file visible in Spring Boot
[Ruby] I want to extract only the value of the hash and only the key
Strict_loading function to suppress the occurrence of N + 1 problem added from rails 6.1
[CircleCI] I was addicted to the automatic test of CircleCI (rails + mysql) [Memo]
[Rails] Use devise to get information about the currently logged in user
How to solve the local environment construction of Ruby on Rails (MAC)!
How to change the value of a variable at a breakpoint in intelliJ
[Rails] The cause of not being able to post was in form_with
Android development, how to check null in the value of JSON object
[Ruby On Rails] How to search the contents of params using include?