简体   繁体   中英

Rails error “NoMethodError” - Just started to use Rails

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 following 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 (ie 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:

  1. Stick to one instance variable to load the products.
  2. 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?)
  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM