Reputation: 861
What I'd like to do is to save the shop_id
in the Item
model.
My models are as followings;
models
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
schema
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
How can I create controller new
and create
to save shop_id
in items
?
I can get the parameter such as Shop.find_by(id: params[:shop_id])
It would be appreciated if you could give me any suggestion.
UPDATE
When I try @Saad's answer, NoMethodError
was displayed as below.
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'
The line of new.html.erb:4 is as following (I haven't use partial _form.html.erb
so far);
<%= form_for(@item, url: shop_items_path, method: :post) do |f| %>
UPDATE2
routes.rb
is as below.
routes.rb
Rails.application.routes.draw do
...
resources :items, only: [:new, :create, :edit, :update]
resources :shops do
resources :items
end
...
Upvotes: 0
Views: 128
Reputation: 161
Improving the previuos code and assuming you shops and items controller are nested:
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 %>
Upvotes: 1
Reputation: 1904
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) %>
Upvotes: 0