Is ActiveResource buggy or am I ?

Hi, I'm currently working with ActiveResource and I have some troubles
with it.
I have two models on the server side, Artist and Song

Songs: belong_to :artist and Artist: has_many :songs

I also have two controllers methods :
A method songs in the ArtistsController that return his songs
and a list_by_artist in the SongsController that return all the songs
for an artist.

All of this is Restful.
  map.resources :artists, :member => {:songs => :get}
  map.resources :songs, :collection => {:list_by_artist => :get}

I know that these two methods does the same thing and I will keep only
one of them at the end but :

I wan't to be able to retrieve all the songs of an artist in the
client side (with ActiveResource) as Songs objects

I can do :
Artist.find(1).get(:songs) to retrieve an Array
but
Artist.find(1).find(:songs) gives me a NoMethodError for the find
method

I can also do

Song.get(:list_by_artist, :id => 1) #again an Array...
but
Song.find(:list_by_artist, :id => 1) gives me :

ArgumentError: expected an attributes Hash, got []
        from /var/lib/gems/1.8/gems/activeresource-2.1.0/lib/
active_resource/base.rb:883:in `load'
        from /var/lib/gems/1.8/gems/activeresource-2.1.0/lib/
active_resource/base.rb:639:in `initialize'
        ...

Looks like Rails try to instanciate a record where it should
instantiate a collection.

Is there any way to solve this ?
Is my method buggy, or is it Rails ?

if you want to get the songs from a artist you can do like i said before
or:

@songs = Song.find_by_artist_id(1) # guess you have a artist_id on songs

if I'm not mistaken this is the right way...

Sorry, to retrieve all the songs from an artist you call

@songs = Song.find_all_by_artist_id(1) # guess you have a artist_id on
songs

if you use the find_by_artist_id, you would get just one song instead of
all of them

Will this work even though the two models are ActiveResource based? I
didn't think it provided you with the finder methods on ActiveResource
models.

Yes all this find_by_*** stuff and even
@artist = Artist.find(1)
@songs = @artist.songs
doesn't work just cause it should not wok, I don't want to be able to
do anything on my "server" models, just the stuff that the RESTFUL
webservice "describe" (that means that I have to call URL, not server
models methods).

The right way to do this is the

Artist.find(1).get(:songs)
or
Song.get(:list_by_artist, :id => 1)

but as I say previously, this return an Array.

I'm not sure that
Artist.find(1).find(:songs)
should work (find is not defined for an ActiveResource object)
but
Song.find(:list_by_artist, :id => 1)
should work according to the doc, but it just doesn't work according
to my test :slight_smile:

Any other idea ?

Ryan Bigg wrote:

Will this work even though the two models are ActiveResource based? I
didn't think it provided you with the finder methods on ActiveResource
models.

Ops.. that's right it won't work... my mistake...

I'm a bit confused. Why not just say:

artist.songs (that'll return all the songs for a given artist
object) or
Song.find_by_artist_id(1) which will return all the songs where
artist ID is one

If you're not able to do that in script/console then your models are
not defined correctly.

Artist < ActiveRecord::Base should have "has_many :songs" and
Song < ActiveRecord::Base should have "belongs_to :artist"

I think ActiveRecord is pretty tight - I haven't experienced any bugs
(well just one but it was some really far out funky thing). The stuff
you are doing is run-of-the-mill every day AcitveRecord.

If you're wanting to do it REST style then you need to define some
nested routes. That'll give you something like /artists/1/songs/4
for song with ID of 4, which belongs to artist 1. That has more to do
with ActiveResource than ActiveRecord.

Nicholas

You obviously didn't quite read the first email, or the title of this
thread.

He's using Active*Resource* models, not ActiveRecord. The dynamic
finders you so trumpet are not available to him!

Please read thoroughly next time!

So nobody has any idea ?

Should I submit a bug in Lighthouse ?

Ok so I'll answer my own question :slight_smile:

In fact, the
Person.find(:managers)
example written by Ryan daigle and DHH doen't work (anymore?)
http://ryandaigle.com/articles/2007/4/26/what-s-new-in-edge-rails-activeresource-gets-custom-methods

You have to write
Person.find(:all, :from => :managers)
and if you wants some params :
Person.find(:all, :from => :managers, :params => {:office =>
"Chicago"})
this will make a call to
http://webservice_site/persons/managers.xml?office=Chicago
and returns the result as real ActiveResource objects !

Hope that can help anyone :slight_smile:

This is very helpful, I was getting the same error about a month ago
and just gave up. Thanks for giving me a renewed interest and idea to
tackle the problem :slight_smile: