Hello,
I’m trying to make ActiveResource work with nested attributes and the
fields_for tag.
I started with a typical Rails application, with two ActiveRecord models
with one to many relationship (one band has many members).
In view ‘bands/new.html.erb’ I have something like this:
<%= form_for @band do |f| %>
<%= f.label: name %>
<%= f.text_field: name %>
<% f.fields_for: members do |member_form| %>
<%= member_form.label: name %>
<%= member_form.text_field: name %>
<%= member_form.label: Instrument %>
<%= member_form.text_field: Instrument %>
<% end %>
<%= f.submit >
<% end %>
In the controller I get this data as follows (in the params hash):
{
band: {
name: ‘band name’,
members_attributes: [
{name: ‘member name’ instrument: ‘some instrument’}
]
}
}
When I send this params to ActiveRecord’s new or create it creates the
band
and members. So far so good.
So I moved the ActiveRecord models into a service and replaced them with
ActiveResource models.
However when I send the request to the service ActiveResource change
these
parameters in a strange way. He turns the ‘members_attributes: […]’ in
something like this:
members_attributes: [
{ members_attribute: { name: ‘member name’ instrument: ‘some
instrument’ }}
]
And the ActiveRecord on the other side cannot treat this.
Does anyone have any idea how to prevent this behavior (or why it
happens)?
In a second attempt I replaced the Band.create by Band.post(nil, {},
params[:band].to_json) (which makes a request directly to the service
without going through the ActiveResource::Base#load that appears to be
source of the problem), but ActiveResource does a post to ‘/bands/.json’
instead of ‘/bands.json’. I patched ActiveResource’s
‘custom_method_collection_url’ method, so the post goes to the right
url,
but i have not yet submitted a push request because I don’t know if this
will be usefull for everyone.
Actually I’m more concerned with understanding why ActiveResource’s
default
behavior is so strange.
Anyone know what the purpose of the method
ActiveRecord::Base#find_or_create_resource_for_collection? (I know what
it
does, i just don’t understand why it does it). Wouldn’t it be easier if
ActiveResource simply passes my parameters for the service?
If someone can help me I would be grateful.