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 ?
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
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.
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 !
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