Home Ask Login Register

Developers Planet

Your answer is one click away!

greetification February 2016

Rails 4 has_many though where filtering

I'm trying to figure out if it's possible to group/filter/select by a records' attribute though a join table. While I understand there are other ways of achieving the same result (one of which I use below) I was wondering if the same could be achieved with a HMT relation.

The models are as follows:

class Foo < ActiveRecord::Base
  has_many :foo_bars
  has_many :bars, through: foo_bars

  has_many :group_a_bars, -> where { foo_bars.bar.bar_group_id: 1 }

class Bar < ActiveRecord::Base
  # == Schema Information
  # Table name: bars
  # bar_group_id :integer          not null

  belongs_to :bar_group

class FooBar < ActiveRecord::Base
  belongs_to :foo
  belongs_to :bar

class BarGroup < ActiveRecord::Base
  has_many :bars

What I would like to be able to do in the view is something like: #{foo.group_a_bars} which would all of the FooBars that have bars that belong to the first bar_group

The same could be accomplished with something like:

foo.foo_bars.find_all{ |foo_bar| foo_bar.bar.bar_group_id == 1 }

EDIT: Following the advice of @smathy I added a join and got it working with the following:

class Foo < ActiveRecord::Base
  has_many :foo_bars
  has_many :bars, through: foo_bars

  has_many    :group_a_bars,
                ->              { joins(:bar).where(bars: { bar_group_id: 1 }) },
                class_name:     "FooBar",
                source:         :bar


smathy February 2016

Yes, it'll be something like this:

has_many :group_a_bars,
  -> { joins(:bar).where( bar: { bar_group_id: 1 } ) }, through: :foo_bars, class_name: "Bar"

You might need a :source option in there too.

Post Status

Asked in February 2016
Viewed 1,920 times
Voted 9
Answered 1 times


Leave an answer

Quote of the day: live life