0

On Rails Console, tried to find some data. Model: User

class User < ApplicationRecord    
  scope :active,    -> { where(status: true) }
  scope :inactive,  -> { where(status: false) }    
end

Rails Console

users = User.all
User Load (0.8ms)  SELECT  `users`.* FROM `users` LIMIT 11

Output - User objects

#<ActiveRecord::Relation [#<User id: 1, name: "John", status: true >,#<User id: 2, name: "Micheal", status: false >,#<User id: 3, name: "Denis", status: true >,#<User id: 4, name: "Arnold", status: true> ...]>

Now try to find an active user from the above object.

active_users = users.active
User Load (0.2ms)  SELECT  `users`.* FROM `users` WHERE `users`.`status` = TRUE LIMIT 11

Output - Users with active status

#<ActiveRecord::Relation [#<User id: 1, name: "John", status: true >,#<User id: 3, name: "Denis", status: true >,#<User id: 4, name: "Arnold", status: true > ...]>

Here, tried to find the active users from the ActiveRecord Object, but somehow SQL query ran at the database instead of filtering records within the object.

Is this the right way to filter objects or any other approach?

4
  • 1
    Having a column named "status" that's a boolean is definately not the right approach. Commented Oct 4, 2023 at 14:47
  • @max good one. LOL, I even didn't note it when wrote the answer Commented Oct 4, 2023 at 15:03
  • @max - Please suggest the column name - for example - make the user active/inactive - active as the column name with a boolean type right? Commented Oct 5, 2023 at 7:52
  • 1
    active would make a lot more sense as a boolean. But you could also use an enum instead of a boolean. railstips.org/blog/archives/2012/10/10/… Commented Oct 5, 2023 at 11:22

1 Answer 1

0

Looks like here two misunderstandings: about relations and about scopes

Active Record relation object is some kind of Ruby wrapper over SQL query. And it is executed only when some method is called on the relation. For example each, or first, or some other. It doesn't invoke request to the database when you just chain relation methods. That's simplified idea of the relation

For example you have such method

def active_users
  users = User.all
  active_users = users.active
end

and call it as puts active_users, in this case it will be just one query SELECT * FROM users WHERE active = TRUE

If you try to execute method body line by line in the rails console, it will be two queries (SELECT * FROM users and SELECT * FROM users WHERE active = TRUE). That's because under the hood in the console inspect method is invoked

It is very common pattern in rails to use such chaining

users = User.all
users = users.active if only_active_needs?
users = users.recent_registerd if only_recent_registered_needs?
puts users

In this example only one query will be executed (only on the last line). Note again that line by line executing in the console could invoke three queries

scope adds class method. Basically it should return relation. As you can guess, one of the feature of of the scopes is chaining / combining

So your attempt to filter records looks good. Sometimes second query will be executed. It is OK

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.