undefined method + method(argument)

Hi.. I would appreciate some help with the following, because I have
tried to find the solution on the web, but I am still no closer to
resolving my issue..

I have a store_controller with an index method and a view for index..

I have also created a new method called find_first_in_group. This
method does not have a view.. I want to call it from the index view..
Also, this method needs an argument to look up a specific field.

In other programming languages it would be something like:
find_first_in_group(image_url). When I try this it says 'undefined
method'. How to tell it where to find the method?

Where are you calling find_first_in_group and what is it supposed to do.

Luke

Can you show the code where you are calling it, with some context
around it, and the code of the method please? Also which files they
are in and the exact error message (and show which line the error
message is indicating).

Colin

I have a store_controller with an index method and a view for index..

I have also created a new method called find_first_in_group. This
method does not have a view.. I want to call it from the index view..
Also, this method needs an argument to look up a specific field.

So you've added a method to your controller, and you want to call that
method from a view? If so, you need to define it as a "helper method"
in the controller:

  helper_method :find_first_in_group

BUT... without a bit more information, it's not possible to say for
sure, but it's possible that it would be more appropriate to put the
method in a model as a class method. But hard to say with what you've
given us.

In other programming languages it would be something like:
find_first_in_group(image_url).

In Ruby it's exactly the same - although it's common to drop the parentheses :wink:

Thanks guys.. Here is some further information to help you determine
what the problem is..

*************Index View(Store)*******************

<% if @cameras.count > 1 then %>
  <% @cameratypes.each do |camera| -%>
  <% @image_url = find_first_in_group(camera.camtype)%>
  <%= link_to(image_tag(@image_url)) %>
  <div>
    <h3><%=h camera.camtype%></h3>
  </div>
  <% end %>
<% end %>

*************Store_controller*******************

class StoreController < ApplicationController
  def index
    @cameras = Camera.find_cameras_for_sale
    @cameratypes = Camera.find_cameras_by_camtype
    @cameramakes = Camera.find_cameras_by_make
  end

##This is only suppose to pass the value on to the main camera model
  def find_first_in_group(camtype)
    Camera.find_first_group_image(camtype)
  end
end

*************Camera model***********************
####Just an extract of the specific method being used

  def self.find_first_group_image(camtype)
    find(:first,
         :select => "image_url",
         :conditions => ["camtype = ?", camtype])
  end

****************Error message*******************

NoMethodError in Store#index

Showing app/views/store/index.html.erb where line #5 raised:

undefined method `find_first_in_group' for
#<ActionView::Base:0x7f6bef401980>

Extracted source (around line #5):

2:
3: <% if @cameras.count > 1 then %>
4: <% @cameratypes.each do |camera| -%>
5: <% @image_url = find_first_in_group(camera.camtype)%>
6: <%= link_to(image_tag(@image_url)) %>
7: <div>
8: <h3><%=h camera.camtype%></h3>

Can someone, please, please, pretty please, with sugar and icing on top,
get back to me on this? I know it is going to be something simple..
Don't mean to be pushy, but I've got a deadline to meet today.. And I am
pulling my hair out.. :frowning:

Michael Pavling wrote in post #954819:

On 16 October 2010 15:46, Evanoshki Brataslavainskinski

So you've added a method to your controller, and you want to call that
method from a view? If so, you need to define it as a "helper method"
in the controller:

  helper_method :find_first_in_group

BUT... without a bit more information, it's not possible to say for
sure, but it's possible that it would be more appropriate to put the
method in a model as a class method. But hard to say with what you've
given us.

In other programming languages it would be something like:
find_first_in_group(image_url).

In Ruby it's exactly the same - although it's common to drop the
parentheses :wink:

Thanks to Michael Pavling for guiding me in the right direction

Did you try Michael's suggestion of adding this to your controller?

helper_method :find_first_in_group

This probably isn't the best approach, but you could change line 5 to something like this:
<% @image_url = Camera.find_first_group_image(camera.camtype)%>

HTH

Luke

Luke Cowell wrote in post #954878:

Did you try Michael's suggestion of adding this to your controller?

helper_method :find_first_in_group

This probably isn't the best approach, but you could change line 5 to
something like this:
<% @image_url = Camera.find_first_group_image(camera.camtype)%>

HTH

Luke

Yes thanks Luke.. That was what I was looking for..

Thanks guys.. Here is some further information to help you determine
what the problem is..

You do seem to be jumping around the houses a little to get the record
you're after... you have a controller method that calls a class method
on a model, which you make a helper_method to use in a view, which you
access while looping through instances of the model that the class
method is attached to...

I would simplify it a little (although there are probably better ways
to do it by association... are "CameraTypes" a model?):
anyway... make the model's class method an instance method, and access
it from each instance of the camera object.

*************Camera model***********************
def find_first_group_image
find(:first,
:select => "image_url",
:conditions => ["camtype = ?", self.camtype])
end

*************Index View(Store)*******************

<% if @cameras.count > 1 then %>
<% @cameratypes.each do |camera| -%>
<% @image_url = camera.find_first_in_group %>
<%= link_to(image_tag(@image_url)) %>
<div>
<h3><%=h camera.camtype%></h3>
</div>
<% end %>
<% end %>

PS All of the "find cameras by xxx" methods... are you using
named_scopes for them? (judging by the names, I think possibly you
aren't, and you probably should :slight_smile:

It is generally not considered good practice to access model methods
directly from the view. Possibly a better way would be to define an
instance method, image_url, in the Camera class. Then you could say
<%= link_to(image_tag(camera.image_url)) %>

Colin

Colin Law wrote in post #954895:

Luke Cowell wrote in post #954878:

Did you try Michael's suggestion of adding this to your controller?

helper_method :find_first_in_group

This probably isn't the best approach, but you could change line 5 to
something like this:
<% @image_url = Camera.find_first_group_image(camera.camtype)%>

It is generally not considered good practice to access model methods
directly from the view. Possibly a better way would be to define an
instance method, image_url, in the Camera class. Then you could say
<%= link_to(image_tag(camera.image_url)) %>

Right. Colin is being nice, so I'll be less nice: the view should NEVER
EVER EVER touch the database.

I am beginning to think that, for this reason and others, template
languages (such as Mustache) where you can't call *any* model methods
are the way to go...

Colin

Best,