我正在尝试为产品和它的产品创建一个rails应用程序。我创建了一个产品页面,通过它可以创建产品。这个页面工作正常。但是当我尝试为相应的产品创建商品页面并将其重定向到列表页面时,它会在“商品”中显示“NoMethodError”#show 显示/Users/smita/workspace/products/app/views/offers/show.html.erb第9行提出:
未定义的方法`offer_name'为nil:NilClass'
我正在使用rails 4,ruby 2.2.3和mysql数据库
这是我的代码:
products_controller.rb
class ProductsController < ApplicationController
def index
@product = Product.all
end
def list
@products = Product.order("products.product_name ASC")
end
def show
@product = Product.find(params[:id])
end
def new
@product = Product.new
end
def create
# Instantiate a new object using form parameters
@product = Product.new(products_params)
# Save the object
if @product.save
# If save succeeds, redirect to the list action
redirect_to(:action => 'list')
else
# If save fails, redisplay the form so user can fix problems
render('new')
end
end
def delete
@product = Product.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to :action => 'list', notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def products_params
params.require(:product).permit(:product_name, :product_desc, :product_image, :product_rate)
end
end
product.rb
class Product < ActiveRecord::Base
has_many :offers
end
CreateProducts
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string "product_name"
t.string "product_desc"
t.string "product_image"
t.integer "product_rate"
t.timestamps null: false
end
end
end
产品/ list.html.erb
<div>
<h2>Products</h2>
<%= link_to("Add New Product", {:action => 'new'}) %>
<table>
<tr>
<th>Product Id</th>
<th>Product Name</th>
<th>Product Desc</th>
<th>Product Image</th>
<th>Product Rate</th>
</tr>
<% @products.each do |product| %>
<tr>
<td><%= product.id %></td>
<td><%= product.product_name %></td>
<td><%= product.product_desc%></td>
<td><%= product.product_image%></td>
<td><%= product.product_rate %></td>
<td>
<%= link_to("Show", {:action => 'show', :id => product.id}) %>
<%= link_to("Edit", {:action => 'edit', :id => product.id}) %>
<%= link_to("Delete", {:action => 'delete', :id => product.id}, data: { confirm: 'Are you sure you want to delete this entry ?' }) %>
</td>
</tr>
<% end %>
</table>
</div>
products / new.html.erb
<div>
<h2>Create Product</h2>
<%= form_for Product.new ,:url => {:action => :create, :controller => :products} do |f| %>
<table>
<tr>
<th>Product Name</th>
<td><%= f.text_field(:product_name) %></td>
</tr>
<tr>
<th>Product Desc</th>
<td><%= f.text_field(:product_desc) %></td>
</tr>
<tr>
<th>Product Image</th>
<td><%= f.text_field(:product_image) %></td>
</tr>
<tr>
<th>Product Rate</th>
<td><%= f.text_field(:product_rate) %></td>
</tr>
</table>
<div>
<%= submit_tag("Save Product") %>
</div>
<% end %>
</div>
产品/ show.html.erb
<%= link_to("<< Back to List", {:action => 'list'}) %>
<div>
<h2>Show Product</h2>
<table>
<tr>
<th>Product Name</th>
<td><%= @product.product_name %></td>
</tr>
<tr>
<th>Product Desc</th>
<td><%= @product.product_desc %></td>
</tr>
<tr>
<th>Product Image</th>
<td><%= @product.product_image %></td>
</tr>
<tr>
<th>Product Rate</th>
<td><%= @product.product_rate%></td>
</tr>
</table>
</div>
offers_controller.rb
class OffersController < ApplicationController
def index
@offer = Offer.all
end
def list
@offers = Offer.order("offers.offer_name ASC")
end
def show
@offer = Offer.find_by_id(params[:id])
end
def new
@offer = Offer.new
end
def create
# Instantiate a new object using form parameters
@offer = Offer.new(offers_params)
# Save the object
if @offer.save
# If save succeeds, redirect to the list action
redirect_to(:action => 'list', notice: 'offer was successfully created.' )
else
# If save fails, redisplay the form so user can fix problems
render('new')
end
end
def delete
@offer = Offer.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to :action => 'list', notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def offers_params
params.require(:offer).permit(:product_id, :offer_name, :offer_start_date, :offer_end_date, :offer_description)
end
end
offer.rb
class Offer < ActiveRecord::Base
belongs_to :offers
accepts_nested_attributes_for :offers
end
CreateOffers
class CreateOffers < ActiveRecord::Migration
def change
create_table :offers do |t|
t.string "product_id"
t.string "offer_name"
t.string "offer_start_date"
t.string "offer_end_date"
t.string "offer_description"
t.timestamps null: false
end
end
end
报价/ list.html.erb
<div>
<h2>Offers !!!</h2>
<%= link_to("Add new offers", {:action => 'new'}) %>
<table>
<tr>
<th>Product Id</th>
<th>Offer Id</th>
<th>Offer Name</th>
<th>Offer start date</th>
<th>Offer start date</th>
<th>Offer description</th>
</tr>
<% @offers.each do |offer| %>
<tr>
<td><%= offer.id %></td>
<td><%= offer.offer_name %></td>
<td><%= offer.offer_start_date %></td>
<td><%= offer.offer_end_date %></td>
<td><%= offer.offer_description %></td>
<td>
<%= link_to("Show", {:action => 'show', :id => offer.id}) %>
<%= link_to("Edit", {:action => 'edit', :id => offer.id}) %>
<%= link_to("Delete", {:action => 'delete', :id => offer.id}, data: { confirm: 'Are you sure you want to delete this entry ?' }) %>
</td>
</tr>
<% end %>
</table>
</div>
报价/ new.html.erb
<div>
<h2>New Offers</h2>
<%= form_for Offer.new ,:url => {:action => :create, :controller => :offers} do |f| %>
<table>
<tr>
<th>Offer Name</th>
<td><%= f.text_field(:offer_name) %></td>
</tr>
<tr>
<th>Offer start date</th>
<td><%= f.text_field(:offer_start_date) %></td>
</tr>
<tr>
<th>Offer end date</th>
<td><%= f.text_field(:offer_end_date) %></td>
</tr>
<tr>
<th>Offer description</th>
<td><%= f.text_field(:offer_description) %></td>
</tr>
</table>
<div>
<%= submit_tag("Save offer") %>
</div>
<% end %>
</div>
报价/ show.html.erb
<%= link_to("<< Back to List", {:action => 'list'}) %>
<div>
<h2>Show offers</h2>
<table>
<tr>
<th>Offer Name</th>
<td><%= @offer.offer_name %></td>
</tr>
<tr>
<th>Offer start date</th>
<td><%= @offer.offer_start_date %></td>
</tr>
<tr>
<th>Offer end date</th>
<td><%= @offer.offer_end_date %></td>
</tr>
<tr>
<th>Offer description</th>
<td><%= @offer.offer_description %></td>
</tr>
</table>
</div>
请让我知道我哪里出错了。谢谢!
答案 0 :(得分:1)
您应该更改设置,以便在单击产品时获得商品的索引。您可以使用nested resources
:
#config/routes.rb
resources :products do
resources :offers, only: [:index, :show, :new, :create] #-> url.com/products/:product_id/offers
end
这将允许您“范围”您正在查看的product
周围的优惠流程:
#app/controllers/offers_controller.rb
class OffersController < ApplicationController
before_action :set_product
def index
@offers = @product.offers
end
def show
@offer = @product.offers.find params[:id]
end
private
def set_product
@product = Product.find params[:product_id]
end
end
这必须与相应的model associations:
结合使用#app/models/product.rb
class Product < ActiveRecord::Base
has_many :offers
end
#app/models/offer.rb
class Offer < ActiveRecord::Base
belongs_to :product
end
从表格的外观来看,您需要确保foreign_key
(offers
表中的product_id
)具有相应的offers
:< / p>
-
这样,您就可以访问url.com/products/1/offers
以获取该产品的所有优惠,然后点击url.com/products/1/offers/5
查看该特定优惠。
关于你的错误,
没有方法'offer_name'
...您需要了解Rails中属性的工作方式。
每次调用实例变量时,都使用以下内容:
@product.product_name
@product.product_desc
错误。
您需要为每个对象引用各种属性。属性基本上就是数据库列名,在您出于某种原因添加对象名之前就已经拥有了这些名称。
要摆脱错误,您基本上只需要 引用属性名称本身:
<% @offers.each do |offer| %>
<tr>
<td><%= offer.id %></td>
<td><%= offer.name %></td>
<td><%= offer.start_date %></td>
<td><%= offer.end_date %></td>
<td><%= offer.description %></td>
</tr>
<% end %>