Home Rails scope where account has user
Reply: 3

Rails scope where account has user

almo
1#
almo Published in 2017-11-08 19:01:25Z

I have an account and a user model where an account has_one user. So in my user table I have the account_id.

I want to create a scope for my accounts where I can pass has_user = TUE/FALSE and it returns the accounts with/without user.

scope :has_user, -> (has_user) { where(...) }

Can anybody help how to write this scope?

Sebastian Palma
2#
Sebastian Palma Reply to 2017-11-08 19:39:41Z

I think you could create two scopes, one to ask for Accounts with user associated and other for the opposite, this way you avoid passing arguments and can use where and where.not, like:

class Account < ApplicationRecord
  has_one :user

  scope :has_user, -> { includes(:user).where.not(users: { account_id: nil }) }
  scope :has_not_user, -> { includes(:user).where(users: { account_id: nil }) }
end

Other way you could create a class method which accepts the boolean value and using an if statement to check with where and/or where.not:

def self.has_user(condition)
  if condition
    includes(:user).where.not(users: { account_id: nil })
  else
    includes(:user).where(users: { account_id: nil })
  end
end

Out of curiosity:

def self.has_user(bool)
  hash = { users: { account_id: nil } }
  query = ->(assoc) { bool ? assoc.where.not(hash) : assoc.where(hash) }
  query.(includes :user)
end
Sean Huber
3#
Sean Huber Reply to 2017-11-08 19:17:55Z

Using raw sql you could write a more efficient query using JOINS but this should work:

scope :has_user, -> (has_user) { 
  account_ids = User.where.not(account_id: nil).pluck(:account_id)
  has_user ? where(id: account_ids) ? where.not(id: account_ids)
}

If Account has_one User I assume then that User belongs_to Account and you have an account_id on your users table.

Ashik Salman
4#
Ashik Salman Reply to 2017-11-09 13:57:47Z

Other way would be,

class Account < ApplicationRecord
  has_one :user

  scope :has_user, ->(has_user = true) {
    criteria = (has_user == true ? 'IN' : 'NOT IN')
    where("id #{criteria} (SELECT DISTINCT(account_id) FROM users)")
  }
end

Default value true is assigned for has_user variable

Account.has_user # Accounts with user

Account.has_user(false) # Accounts without user

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.34635 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO