views:

1208

answers:

2

I am using ActiveResource in Rails to manage entities in a separate database over REST.

I have been trying to explicitly manage the IDs of the remote resources, as for the current case it is simplest to just re-use the local resource's ID, rather than maintain a different field.

Unfortunately I have not been able to get this working as the code for new? in ActiveResource::Base is

  def new?
    id.nil?
  end

and save is

 def save
   new? ? create : update
 end

So from that by definition it is impossible to set an ID of a resource and save it as a new resource.

create and update are protected methods, so if I hacked the ActiveResource::Base code perhaps that would make it work, but I am loath to do that.

Is there a correct way of doing this? Or is what I am trying to do just bad, and I shouldn't do it?

+1  A: 

You're working against the intentions of ActiveResource. ActiveResource provides an interface to REST webservices, which by convention return the assigned ID when you do a create.

That said, if you control the resource you're using, and you have modified its behavior to take an ID when saving a new record, you could modify ActiveResource::Base to conform. It's really not uncommon for folks in Rails to make additions and changes to base classes; you just put your patch in lib and include it somewhere in your startup stuff.

I don't think it's a good idea, necessarily, but it is possible. :)

Sarah Mei
+1  A: 

In new rails (tested 2.3.2) id can be set, as saving logic has changed a bit (now records have boolean field @newrecord to eliminate that id.nil?).

record = Model.new
record.id = 123
record.save!
Vasfed
Just to clarify - is that in ActiveResource or ActiveRecord? (any link for reference?)
DanSingerman
Oops, misread a bit, sorry - above is correct for ActiveRecord. For resource case it's better to rename the ID field for the comunication thus no need for changing rails.
Vasfed
Or you can simply alter remote controller update action to actually do a "create_or_update"
Vasfed