简体   繁体   中英

Rails 4 new form defaults from params

I am using form_for in the _form.html.erb view in order to create my form for both the edit and new actions, as per a standard scaffold.

I have a model Owner which has_many pets.

I would like to put an html link on my views/owners/show.html.erb to create a new pet for said owner. This link will point to the new action of pets_controller.rb which when accessed will render the view in pets/new.html.erb

What I want to happen is for the the owner_id to be passed with the link in the url to the new action of pets_controller.rb and then be used as the default for a collection_select in pets/new.html.erb

So I have a link to create a new pet but because that link was on a specific owner page, I want the form to create a new pet to have that owner already set, so the user does not have to select from the list.

This has to be done without changing the behaviour of the edit action/view in pets.

I know that I can pass GET arguments then access them in the controller via params, then create variables in the action which are passed to the view. I can then manually check for a default and set it in the view. I do not need assistance in coding if this is the only solution.

Is there is a better way to do this? A format with which I can pass the params such that the view will just pick them up? Without manually editing my controllers and views?

While my personal inclination would be to do as you said and pass a parameter in the link helper and then access the params array in the pets view, you may find that this is the perfect opportunity to explore Nested Resources . Essentially, you could declare owners/:owner_id/pets/:pet_id route with:

resources :owners do
  resources :pets
end

You could then link to this route, and reference :owner_id without having to append the query string to the URI (making somewhat cleaner for reuse).

This is likely more work for you, but also potentially more extensible (and certainly more inline with the Rails way of doing things).

REVISION

Added the following regarding link helpers to the comments, but wanted to reflect it in the answer as well.

To show a pet should be:

<%= link_to owner_pet_path( owner_variable, pet_variable) %>

To view pets' index index should be:

<%= link_to owner_pet_path( owner_variable ) %>

The answer given to this question is fantastic.

As @ConnorCMcKee suggests it would be wise to consider nesting your routes. However, if you are a beginner as myself I found that it helped my learning to simply nest my second controller into the first (ie nest PetsController into OwnersController) as a first step. Then afterwards I would continue with the routes.

The method would be something like:

1./ In owners/index.html.erb :

Links to PetsController index action

The key to make this work is to send the :owner_id in your link parameters. Then that Pets index action will have access to that :owner_id and know which :owner_id called it.

2./ In PetsController you would then be able to find that Owner using that id, like so:

params[:owner_id]

Then your actions can start to take advantage of knowing what Owner called them. Remember though that all your redirects inside your PetsController need to preserve params[:owner_id] . That is because once you are inside that nested structure you have to maintain it and stay inside it and always know which :owner_id you are working with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM