ActiveRecord as a neat trick/ability which a lot of folks are not aware of.
You can pass a block to association, for example:
class Account < ApplicationRecord
has_many :users, -> { where(admin: true) }
end
class User < ApplicationRecord
belongs_to :account
end
What makes this even more interesting is that you can have multiple associations to the same model with different name and conditions.
class Account < ApplicationRecord
has_many :users
has_many :admin_users, -> { where(admin: true) }, class_name: "User"
end
Calling @account.users
will return collection of all users, but calling @account.admin_users
will return collection of only admin users.
To make things even more interesting, when creating a new record through the association will comply with the association condition.
@account.admin_users.create(name: "Admin User")
creates a new user with admin
set to true
.
Since, condition executes in the context of the association object, you can also use scopes.
class Account < ApplicationRecord
has_many :users
has_many :admin_users, -> { admins }, class_name: "User"
end
class User < ApplicationRecord
belongs_to :account
scope :admins, -> { where(admin: true) }
end
@account.admin_users # Works the same as examples above
This associations will also work for eager loading also, calling
Account.includes(:admin_users)
will eager load admin users.
ActiveRecord can accomplish this because associations are built from Relation
objects, and you can use Relation
syntax to customize them.
Isn't this neat!
Top comments (0)