Quite experienced but self taught with PHP/MySQL and playing about with Rails. Really love what i’ve done with it do so far but am seriously struggling with what in my mind should be really simple; joining data from various tables together and then displaying it in various views. I think I get the concept of Active Record, I just can’t seem to get it to work they way I want.
I’m working on building a fairly involved music cataloging system ala Discogs, with artist, release, product, track and label levels and have the following models:
class Artist < ActiveRecord::Base
has_and_belongs_to_many :releases
end
class Release < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :release
has_many :tracks
end
class Tracks < ActiveRecord::Base
has_and_belongs_to_many :products
end
Eventually, I want to introduce territories, sales and other data but until I nail the basics above I can’t move fwd.
In my products controller I have:
@product = Product.find(:all, :include => :release)
Which produces:
Processing by ProductsController#index as HTML
Product Load (0.1ms) SELECT "products".* FROM "products"
Release Load (0.2ms) SELECT "releases".* FROM "releases" WHERE "releases"."id" IN (1, 2, 3, 10, 4)
But I am thinking this might be unnecessary if my associations are correct?
In my products view for example I want to list products with the title pulled in from the releases table. I’ve tried the following but get a ‘NoMethodError’ on title:
<% @product.each do |product| %>
<tr>
<td><%= product.title %></td>
<td><%= product.cat_no %></td>
<td><%= product.barcode %></td>
<td></td>
</tr>
<% end %>
Help!!
Massive thanks in advance.
Ryan
The above query is generated because you have used :include=>:association(:release in your case) in find method.This the property of Rails is called as eager loading widely used for performance optimization.There is no problem in your association I think.
If you have used
@products = Product.all
And in your view page
The method call product.release will create the above query for the ‘n’ number of times the loop executed.(n database hits)
If you use :include option this can be avoided.Rails preloads the related association(:release).(only 1 databse hit)
For more details visit
http://guides.rubyonrails.org/active_record_querying.html
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html