Rails:如何保存关联的父值

时间:2016-06-17 22:21:58

标签: ruby-on-rails ruby-on-rails-4

我想要做的是将shop_id保存在Item模型中。

我的模型如下;

模型

shop.rb

class Shop < ActiveRecord::Base
    belongs_to :order
    has_many :items
    has_many :categories
end

item.rb的

class Item < ActiveRecord::Base
    belongs_to :shop
    has_many :categories
end

模式

ActiveRecord::Schema.define(version: 20160615060137) do

...

  create_table "shops", force: :cascade do |t|
    t.string   "name"
    t.integer  "order_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "items", force: :cascade do |t|
    t.string   "name"
    t.integer  "shop_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

...

end

如何创建控制器newcreate以在shop_id中保存items? 我可以获得Shop.find_by(id: params[:shop_id])

等参数

如果你能给我任何建议,我将不胜感激。

更新

当我尝试@ Saad的回答时,NoMethodError显示如下。

NoMethodError (undefined method `to_key' for #<Item::ActiveRecord_Associations_CollectionProxy:0x007f901e079a30>
Did you mean?  to_query
               to_ary):
  app/views/items/new.html.erb:4:in `_app_views_items_new_html_erb__3601549985910054210_70128472136980'



NoMethodError (undefined method `to_key' for #<Item::ActiveRecord_Associations_CollectionProxy:0x007f901e079a30>
Did you mean?  to_query
               to_ary):
  app/views/items/new.html.erb:4:in `_app_views_items_new_html_erb__3601549985910054210_70128472136980'

new.html.erb:4的行如下(到目前为止我还没有使用部分_form.html.erb);

  <%= form_for(@item, url: shop_items_path, method: :post) do |f| %>

UPDATE2

routes.rb如下所示。

的routes.rb

Rails.application.routes.draw do

  ...

  resources :items,              only: [:new, :create, :edit, :update]

  resources :shops do
    resources :items
  end

  ...

2 个答案:

答案 0 :(得分:1)

改进previuos代码并假设你的商店和物品控制器是嵌套的:

class ItemsController < ApplicationController
  before_action :load_shop

  def index
    @items = @shop.items
  end

  def new
    @item = Item.new
    @item.shop = @shop
  end

  def create
    @item = Item.new(item_params)
    respond_to do |format|
      if @item.save
        format.html { redirect_to shop_item_path(@shop, @item), notice: 'Item was successfully created.' }
        format.json { render :show, status: :created, location: @item }
      else
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  private
  def load_shop
    @shop = Shop.find(params[:shop_id])
  end

  def item_params
    params.require(:item).permit(:name, :shop_id)
  end
end


<%= form_for([@shop, @item]) do |f| %>

    <div class="field">
      <%= f.label :name %><br>
      <%= f.text_field :name %>
    </div>
    <%= f.hidden_field :shop_id%>
    <div class="actions">
       <%= f.submit %>
    </div>
<% end %>

答案 1 :(得分:0)

items_controller.rb

class ItemsController < ApplicationController
  before_action :set_item, only: [:show, :edit, :update, :destroy]

  def index
    @shop = Shop.find(params[:shop_id])
    @items = @shop.items
  end

  def new
    @shop = Shop.find(params[:shop_id])
    @item = Item.new
  end
    def create
    @shop = Shop.find(params[:shop_id])
    @item = Item.new(item_params)

    respond_to do |format|
      if @item.save
        format.html { redirect_to shop_item_path(@shop, @item), notice: 'Item was successfully created.' }
        format.json { render :show, status: :created, location: @item }
      else
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_item
      @shop = Shop.find params[:shop_id]
      @item = @shop.items.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def item_params
      params.require(:item).permit(:name, :shop_id)
    end
end

_form.html.erb

<%= form_for(@item, url: shop_items_path, method: :post) do |f| %>
  <% if @item.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@item.errors.count, "error") %> prohibited this item from being saved:</h2>

      <ul>
      <% @item.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <%= f.hidden_field :shop_id, value: @shop.id %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

index.html.erb

<p id="notice"><%= notice %></p>

<p>
  <strong>Name:</strong>
  <%= @item.name %>
</p>

<p>
  <strong>Shop:</strong>
  <%= @item.shop %>
</p>

<%= link_to 'Edit', edit_shop_item_path(@shop, @item) %> |
<%= link_to 'Back', shop_items_path(@shop) %>