32895

Ruby on Rails: Simple way to select all records of a nested model?

Question:

Just curious, I spent an embarrassing amount of time trying to get an array of all the records in a nested model. I just want to make sure there is not a better way.

Here is the setup:

I have three models that are nested under each other (Facilities >> Tags >> Inspections), producing code like this for routes.rb:

map.resources :facilities do |facilities| facilities.resources :tags, :has_many => :inspections end

I wanted to get all of the inspections for a facility and here is what my code ended up being:

def facility_inspections @facility = Facility.find(params[:facility_id]) @inspections = [] @facility.tags.each do |tag| tag.inspections.each do |inspection| @inspections << inspection end end end

It works but is this the best way to do this - I think it's cumbersome.

Answer1:

You can use has_many :through association. In your models:

# Facility model has_many :tags has_many :inspections, :through => :tags # Tag model belongs_to :facility has_many :inspections

And you can get all inspections like this:

@inspections = Facility.find(params[:facility_id]).inspections

But if you have HABTM relation between Facility and Tag it will be more complicated and you would have to write some sql manualy, like this:

@inspections = Inspection.all(:joins => "INNER JOIN tags ON tags.id = inspections.tag_id INNER JOIN facilities_tags ON tags.id = facilities_tags.tag_id", :conditions => ["facilities_tags.facility_id = ?", params[:facility_id] )

Of course above code depends on your table structure. If you will show it, then it would be easier to give correct answer :). Hope it helps!

Answer2:

@facility = Facility.find(params[:facility_id], :include => {:tags => :inspections})

This executes one query against the database (your original solution would use many of them), and returns a facility object with all the tag and inspections included. Then you can do something like:

@inspections = @facility.tags.map(&:inspections).flatten

Recommend

  • Eclipse Incremental Builder Plugin does not work
  • Firefox add-on to find unclosed HTML elements
  • Detect newline byte from filestream
  • Jekyll plugin to handle categories doesn't work on GitHub
  • HTML 5 local computer hardware specs
  • User.find_for_oauth - where can I find it?
  • Ajax response not being shown inside success function
  • FCM (Firebase Cloud Messaging) in Windows Mobile App (Cordova)?
  • how to write or read from XML config file (.config)
  • How can I create doxygen docs from boost::python docstrings?
  • How to print commands in Python?
  • One html form, several interrelated django forms - how to save?
  • Bloomberg Data… Why doesn't Application.WorksheetFunction.BDH work?
  • Apache POI 3.17 in OSGi
  • How do databases sort Chinese characters?
  • Position Userform differently for each ActiveCell Clicked
  • Make mongoid session read only
  • Matlab to Python Conversion binary file read
  • Embedded or referenced relations
  • How to debug office add-in for mac?
  • web shop (shopping cart) on google app engine
  • How to detect left mouse click but not when the click occur on a UI Button component [closed]
  • UIBarButtonItem's action is not called when in a view with a UIGestureRecognizer
  • C++/CLI Thread synchronization including managed and unmanaged code
  • Arduino making decision according to a packet received from serial port
  • Is it possible to get the word under the mouse cursor in a ``?
  • BeautifulSoup difference between findAll and findChildren
  • NHibernate manually control fetching
  • using System.Speech.Synthesis with Windows10 universal app (XAML-C#)
  • How to make R's read_csv2() recognise the text characters properly
  • accepts_nested_attributes_for practical form use for in Rails 3
  • What's the purpose of QString?
  • Alternative to overridePendingTransition() - Android
  • ActiveRecord query for a count of new users by day
  • Is there a javascript serializer for JSON.Net?
  • How to add date and time under each post in guestbook in google app engine
  • JSON with duplicate key names losing information when parsed
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • Getting 'uninitialized constant' error when using delegate in belongs_to in model
  • Return words with double consecutive letters