I am starting to create my sites in Ruby on Rails these days instead of PHP.
I have picked up the language easily but still not 100% confident with associations :)
I have this situation:
User Model
has_and_belongs_to_many :roles
Roles Model
has_and_belongs_to_many :users
Journal Model
has_and_belongs_to_many :roles
So I have a roles_users
table and a journals_roles
table
I can access the user roles like so:
user = User.find(1)
User.roles
This gives me the roles assigned to the user, I can then access the journal model like so:
journals = user.roles.first.journals
This gets me the journals associated with the user based on the roles. I want to be able to access the journals like so user.journals
In my user model I have tried this:
def journals
self.roles.collect { |role| role.journals }.flatten
end
This gets me the journals in a flatten array but unfortunately I am unable to access anything associated with journals in this case, e.g in the journals model it has:
has_many :items
When I 开发者_如何学Pythontry to access user.journals.items
it does not work as it is a flatten array which I am trying to access the has_many association.
Is it possible to get the user.journals
another way other than the way I have shown above with the collect method?
Hope you guys understand what I mean, if not let me know and ill try to explain it better.
Cheers
Eef
If you want to have user.journals
you should write query by hand. As far as I know Rails does has_many :through
associations (habtm is a kind of has_many :through
) one level deep. You can use has_many
with finder_sql
.
user.journals.items
in your example doesn't work, becouse journals
is an array and it doesn't have items
method associated. So, you need to select one journal and then call items
:
user.journals.first.items
I would also modify your journals
method:
def journals
self.roles(:include => :journals).collect { |role| role.journals }.flatten.uniq
end
uniq
removes duplicates and :inlcude => :journals
should improve sql queries.
Similar question https://stackoverflow.com/questions/2802539/ruby-on-rails-join-table-associations
You can use Journal.scoped
to create scope with conditions you need. As you have many-to-many association for journals-roles, you need to access joining table either with separate query or with inner select:
def journals
Journal.scoped(:conditions => ["journals.id in (Select journal_id from journals_roles where role_id in (?))", role_ids])
end
Then you can use user.journals.all(:include => :items)
etc
精彩评论