views:

214

answers:

2

(Warning: Clueless Rails Newbie!)

In my show.html.erb for my albums view, I call a public method in my albums controller:

<% albums_feature = find_albums_with_feature(feature.id) %>

It generates a NoMethodError.

So I copied the method into my Album model and tried calling it from the view as:

<% albums_feature = Album.find_albums_with_feature(feature.id) %>

But this also gets a NoMethodError.

Where should I define this method?

For what it's worth, the method looks like this:

  def find_albums_with_feature(feature_id)
    albums_for_feature = Albums.find_by_sql(  
    ["select al.* from albums al, albums_features alfe
    where al.id = alfe.album_id
    and alfe.feature_id = ?", feature_id])
  end
+2  A: 

In the Album model. Needs self in front though:

def self.find_albums_with_feature(feature_id)
Jarrod
Why does it need 'self'? In Ruby, you don't need 'self' usually? Anyway, after I followed your suggestion I got: "uninitialized constant Album::Albums" when I called Album.find_albums_with_feature(feature.id) from the view. Did I need something else?
pez_dispenser
If you put it in model, than remove "Albums." from "Albums.find...and_so_on".
klew
The self part is the object the method is for, so from a controller you use Album.method, but when calling the method from within its own model you use self.method.Also: klew's answer is probably the way you'll want to go. It's important in Ruby to treat everything as its own object with its own methods, with proper associations.
Jarrod
+5  A: 

If you want to have method that is accesible from view, you have few options:

  • put it in the model
  • put it in the helper
  • put it in the controller and add a line "helper_method :find_albums_with_feature"

But I think you can do it better. Firstly, don't put any finding methods in view. Put it in the controller. Secondly, you don't need to specify your own finding method. Probably you have something like this in your models:

class Album << ActiveRecord::Base
  has_many :albums_features
  has_many :features, :through => :albums_features
end

class AlbumsFeature << ActiveRecord::Base
  belongs_to :album
  belongs_to :feature
end

class Feature << ActiveRecord::Base
  has_many :albums_features
  has_many :albums, :through => :albums_features
end

With it, you can find albums with specific feature like this:

@feature = Feature.find(id)
@albums = @feature.albums

or

@albums = Feature.find(id).albums

and it should be in your controller. In view you should only display results.

If you are looking for more informations about associations, take a look here: http://guides.rubyonrails.org/association_basics.html. I think it's the best place where you can learn about Rails - at least it is for me.

klew
Wow. Terrific. Thanks.
pez_dispenser