Reputation: 21
I have three model Role
, Action
and RoleAction
with some code:
class Role < ActiveRecord::Base
has_many :users
has_many :actions, -> {where role_actions:{status: 1}}, :through => :roleActions
has_many :actions, :through => :roleActions #other context(manager, etc...)
has_many :roleActions
end
class Action < ActiveRecord::Base
has_many :actions, foreign_key: 'parent_id'
has_many :roleActions
has_many :roles, through: :roleActions
end
class RoleAction < ActiveRecord::Base
belongs_to :role
belongs_to :action
end
When I using role.actions
will get actions of role
and have status == 1
in role_actions.
But I want to when I using role.actions("manager")
(with "manager" is context name) will return all action of role.
How can I do?
Thanks!
Upvotes: 2
Views: 288
Reputation: 76774
- You need to keep your associations
snake_case
- You cannot have multiple associations with the same name (IE
actions
)
Here's what I'd do:
#app/models/role.rb
class Role < ActiveRecord::Base
has_many :role_actions
has_many :actions, through: :role_actions do
def status(val)
{ where status: val } # @role.actions.status(1)
end
end
end
#app/models/role_action.rb
class RoleAction < ActiveRecord::Base
belongs_to :role
bleongs_to :action
end
#app/models/action.rb
class Action < ActiveRecord::Base
has_many :role_actions
has_many :actions, through: :role_actions
end
You'll want to look up scopes in Rails - it's bad practice to define conditions in your association query, only to then want to break it. Some would call it an antipattern.
--
If you have the "naked" assocation, you'll be able to scope that however you want. You can also use ActiveRecord association extensions to provide specific functionality on your association itself (as demonstrated above).
role.actions("manager")
This can be achieved by simply invoking the Role
object when looking up the manager value:
@role = Role.find_by name: "manager"
@role.actions #-> all actions for the "manager" role.
Upvotes: 1