Chained search


#1

Hello,

I have:
Messages table with membership_id column
Memberships table with member_id column
Members table with name column

Having a single message m, how do I get the name of the member of the
membership of this message?

The following works ok:
Member.find(Membership.find(m.membership_id).member_id).name

but it seems to me it’s unnecessarily complicated…


#2

On 9 Mar 2009, at 09:50, Pesho P. wrote:

The following works ok:
Member.find(Membership.find(m.membership_id).member_id).name

setup the usual associations (if this makes no sense to you then have
a look at http://guides.rubyonrails.org/association_basics.html)

and then
m.membership.member.name

Fred


#3

Frederick C. wrote:

setup the usual associations (if this makes no sense to you then have
a look at http://guides.rubyonrails.org/association_basics.html)

and then
m.membership.member.name

Thanks, Frederick! I got it working.
However, now I need to do a more complicated/weird query…

In my model:

Message (fields: membership_id, is_pending)
belongs_to Membership

Membership (fields: member_id, team_id, role_id)
belongs_to Member
belongs_to Group
belongs_to Role

all the reverse associations are has_many

I would like to find all pending Messages, which belong to Memberships,
whose group_id is one of the group_id-s where a certain Member m has a
Role “admin”

In other words, each Member is in a Group, and has a Role in this
Group(the triples member-group-role are defined in the model
Membership). On the other hand, each Message is associated to a
Membership. If we look at the two sets:

  1. All Messages with is_pending=true
  2. All the Memberships where Member m has role “admin”
    … then I need the messages from (1.), which belong to the Memberships
    from (2.)

I realize it’s quite complicated, but if you can suggest me another way
to achieve this, I’ll be happy to change my approach.

Thanks!
Petar


#4

On Mar 10, 4:43 pm, Pesho P. removed_email_address@domain.invalid
wrote:

to achieve this, I’ll be happy to change my approach.

One way to do this is to join the tables which have the extra
information so that you can then put conditions on those. So at a
basic level if it was just messages and memberships the raw sql would
be something like

select messages.* from messages
inner join memberships on memberships.id = messages.membership_id
where some conditions on messages and memberships.

You don’t need to write out all this, Message.find :all, :joins
=> :memberships, :conditions => […]

You can join several layers down - there’s some examples at
http://www.spacevatican.org/2008/8/8/nested-includes-and-joins

Fred