Building a nested attribute from multiple parent objects
I'm currently trying to use link_to
with a helper method that creates links for creating items dynamically, rather than using the new_object_path
methods. Rails 3 allows for polymorphic URLs, which fl00r helped me identify and use in the form I was originally searching for. However, while using Rails' polymorphic_url
method as shown here does pass the argument in the http request, the related form field on the returned page isn't filled in, and isn't getting set. I'm trying to build an order_item
from an order
that also is built from a photo
.
Does anyone see what's going wrong here? Related code is below:
# the helper method
def add_cart_button_fo开发者_JAVA技巧r(arr, attr_hash={})
link_to button(:cart_add), polymorphic_url( [:new] + arr, attr_hash )
end
# the call in index.html.haml
= add_cart_button_for [current_order, :order_item], :photo_id => photo.id
# _form.html.haml for order_item
- form_for [ @order, @order_item ] do |f|
%p
= f.label :photo_id
%br
= f.text_field :photo_id
Here's the original question:
I'm trying to create a link to create a [:new, @order, @order_item]
where @order_item.photo_id
can be passed in the link.
Now, I'm not sure if that makes a lot of sense, so I'll try to clarify my problem here.
From what I've seen, Rails 3 has a newish syntax for linking to resource actions using an array structured as [:action, object]
or for deeply nested resources, [:action, parent, child]
. For this particular example, I'm using link_to [:new, @order, :order_item]
. These buttons will be attached to each photo in a photo gallery.
Is it possible to pass the id
of the photo as the attribute photo_id
of the new order item?
So far I've tried link_to [:new, @order, :order_item], :photo_id => photo.id
, but that doesn't seem to work. I've also tried putting :photo_id
in an explicit hash. Is there a way to follow this new syntax and achieve this functionality?
Update: I'm really hoping to find something along the lines of:
link_to "new photo", [:new, @order, :order_item => {:photo_id => photo.id}]
where I'm kind of doing a :build but with more than just the attributes from the builder model being supplied.
UPDATE 11 Apr 2011
I got it working where I can pass an attribute into a get request using polymorphic_url
as seen below:
# the helper method
def add_cart_button_for(arr, attr_hash={})
link_to button(:cart_add), polymorphic_url( [:new] + arr, attr_hash )
end
# the call in index.html.haml
= add_cart_button_for [current_order, :order_item], :photo_id => photo.id
This seems like it should be working. I can see the get request that seems to be working as expected:
Started GET "/orders/1/order_items/new?photo_id=130" for 127.0.0.1 at 2011-04-11 18:11:07 -0400
Processing by OrderItemsController#new as HTML
Parameters: {"photo_id"=>"130", "order_id"=>"1"}
and the url is as expected, but the form doesn't seem to be catching that variable from the url.
The :order_id works. The :photo_id, however, does not appear to be carrying over to the OrderItems#new page. I created a text_field
for :photo_id
, and it's empty every time. It's in the attr_accessible
. I don't see why it's not working.
No.
You can try this
link_to "New ...", polymorphic_url([:new, @order, :order_item], :photo_id => photo.id)
or old school link_to
link_to "New ...", new_order_order_item(@order, :photo_id => photo.id)
I finally figured this thing out.
In my OrderItemsController#new action, my build
function was either taking no parameters or params[:order_item]
as the parameter. Since the parameter passed from the polymorphic_url
wasn't actually related to any object, but was just a raw attribute, I tried simply passing the entire params
hash into the build function. Worked like a charm. So I'm using this code for the link:
= add_cart_button_for [current_order, :order_item], :photo_id => photo.id
and this code in my controller:
def new
@order_item = @order.order_items.build(params)
end
def create
@order_item = @order.order_items.build(params[:order_item])
if @order_item.save
@order.save
flash[:notice] = "Successfully created order item."
redirect_to @order
else
render :action => 'new'
end
end
Now that the entire params hash is getting passed, the form can find the correct photo when building the new order item.
精彩评论