Hopefully this is a very easy problem to solve as I am just starting out with Rails.
I have one database (Products) which contains a number of product attributes including brand, colour and product_type.
I currently have an index page (within productfinder directory) which is able to provide a summary of the products in the database. I am using the followi开发者_Go百科ng code in index.html.erb:
<% @distinctbrands.each do |distinctbrand| %>
<h4><%= distinctbrand %></h4>
<% end %>
Within productfinder_controller.rb i have:
def index
@distinctbrands = Product.find( :all, :order => 'brand ASC', :select => 'brand' ).map{ |i| i.brand }.uniq
@distinctcolours = Product.find( :all, :order => 'colour ASC', :select => 'colour' ).map{ |i| i.colour }.uniq
end
UP TO THIS POINT EVERYTHING SEEMS TO BE WORKING CORRECTLY
Now I would like to add 3 buttons onto my index page, these buttons would enable the user to recalculate the distinctbrands and distinctcolours for a subset of the products - matching either product_type = "new" or "used". The third button would correspond to the results not being filtered at all (i.e. as the index page loads initially).
In a previous question I was advised to add the following code: In productfinder_controller:
before_filter :load_products, :only => [:index, :bybrand, :bycolour, :byprice]
protected
def load_products
@products = Product.by_product_type(params[:product_type])
end
In Product.rb:
scope :by_product_type, lambda{ |product_type| where(product_type: product_type.to_i) unless product_type.nil? }
In index.html.erb
<%= link_to "New", :controller => params[:controller], :action => params[:action], :product_type => 'New' %>
<%= link_to "Used", :controller => params[:controller], :action => params[:action], :product_type => 'Used' %>
<%= link_to "Don't Restrict", :controller => params[:controller], :action => params[:action], :product_type => '' %>
When the application is now run I get a NoMethodError - ProductFinder#Index (while trying to do nil.each The error is associated with <% @distinctbrands.each do |distinctbrand| %>
I wondered if the problem was with the functions defining @distinctbrands and @distinctcolours as the database has now been filtered, however I get the same error for both the following situations:
def index
@distinctbrands = @product.find( :all, :order => 'brand ASC', :select => 'brand' ).map{ |i| i.brand }.uniq
@distinctcolours = @product.find( :all, :order => 'colour ASC', :select => 'colour' ).map{ |i| i.colour }.uniq
end
and
def index
@distinctbrands = Product.find( :all, :order => 'brand ASC', :select => 'brand' ).map{ |i| i.brand }.uniq
@distinctcolours = Product.find( :all, :order => 'colour ASC', :select => 'colour' ).map{ |i| i.colour }.uniq
end
Is somebody able to provide me with a possible solution please? Is the problem to do with @products not being defined within def index? If so, how can this be done?
Many thanks for your time
Using the before_filter, you're creating an instance of @products, but your index is still loading @distinctbrands.
What I think you should do is:
- Stick to one instance variable to load the products.
- Add all the logic for adding the products to that variable in the before_filter and in your model. Use scopes to make the queries chain-able (using Rails 3?)
- Use a condition in the load_products method searching for a params hash to determine if the products should be loaded by the option set in the params, or just all.
So in your model, the load_products method could look like:
def load_products
if params[:product_type]
@products = Product.by_product_type(params[:product_type])
else
@products = Product.find( :all, :order => 'brand ASC', :select => 'brand' ).map{ |i| i.brand }.uniq
end
end
Then in your index update to:
<% @products.each do |product| %>
<h4><%= product.name %></h4>
<% end %>
I might be confused but I see a few different things here. I see brand, color, and type. What is the default view you want show? If they are filtered by type, when does color come into play?
Thanks for all your help - I went through your suggestions again and managed to identify that I had a minor error in product.rb, now it reads:
scope :by_product_type, lambda{|product_type| where(:product_type => product_type) unless product_type.nil? }
All seems to be working well! Thanks again
精彩评论