Combining Ruby on Rails
These days I am starting to build my sites in Ruby on Rails instead of PHP.
I picked up the language easily, but still not 100% sure with the associations :)
I have a situation like this:
User model
has_and_belongs_to_many :roles
Role model
has_and_belongs_to_many :users
Magazine model
has_and_belongs_to_many :roles
So I have a table roles_users
and a tablejournals_roles
I can access custom roles like this:
user = User.find(1) User.roles
This gives me the roles assigned to the user, then I can access the journal model like this:
journals = user.roles.first.journals
This gives me user-specific logs based on roles. I want to be able to access logs likeuser.journals
In my user model, I tried this:
def journals
self.roles.collect { |role| role.journals }.flatten
end
This gives me the logs in a flatten array, but unfortunately I cannot access anything related to the logs in this case, for example in the logs model which has:
has_many :items
When I try to access user.journals.items
it doesn't work as it is a flatten array that I am trying to access the has_many association.
Can I get user.journals
another way than the one shown above with the collect method?
I hope you guys understand what I mean if you don't let me know and I try to explain it better.
Greetings
Eef
a source to share
If you want to have user.journals
, you have to write the request manually. As far as I know, Rails makes associations has_many :through
(habtm is a view has_many :through
) one level. You can use has_many
with finder_sql
.
user.journals.items
doesn't work in your example, becouse journals
is an array and has no method associated with it items
. So, you need to select one log and then call items
:
user.journals.first.items
I would also change your method journals
:
def journals
self.roles(:include => :journals).collect { |role| role.journals }.flatten.uniq
end
uniq
removes duplicates, but :inlcude => :journals
should improve SQL queries.
a source to share
A similar question to fooobar.com/questions/2589392 / ...
You can use Journal.scoped
to create an area with the conditions you need. Since you have a many-to-many association for the log-roles, you need to access the junction table with a separate query or with an internal selection:
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.
a source to share