简体   繁体   中英

Rails - create child record from parent

Feel like an idiot for asking this, but I'm starting to feel like I learned it the wrong way originally.

I might note that I'm not using nested routes.

If I have two models:

class Category < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  belongs_to :category
end

What is the best way to create a new product from the appropriate parent category page?

At the moment I have this on the category page

<%= link_to new_product_path(:category_id => @category) 

Then on the new product page Im using:

<%= form_for @product do |p| %>
  <%= p.hidden_field :category_id, :value => params[:category] %>
  #rest of fields
  #etc
<% end %>

This will work as long as the url parameter survives. However, as soon as the user arrives on this page via the back button or the render 'new' as a result of failed validation, the url parameter is lost and this no longer works.

This is such a simple everyday rails task, there has to be a more reliable method of creating child records from the parent page.

You can change your new and create actions to work similar to as if they were a nested category-product resources, by:

resources :products, except: [:new, :create] do
  get  :new, path: 'products/:category_id/new'
  post :create, path: 'products/:category_id'
end

You would still have to do:

<%= link_to new_product_path(:category_id => @category) %>

But you will not have to add the hidden fields in your form. Instead in your create action inside your controller you can do:

category = Category.find params[:category_id]
category.products.build(product_params)

Doing it this way you will not be utilizing url parameters, and failed validations should prompt you back to the proper page.

All instance variables you define in your controller action are present in the view. So if you define @category in your controller you can access it in the view using <%= @category %> . This way you can avoid using params inside your view.

def new 
  @category = Category.find(params[:category])

def create
  @category = Category.find(params[:category])

<%= form_for @product do |p| %>
  <%= p.hidden_field :category_id, :value => @category.id %>

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