商品#how中的NoMethod错误

时间:2015-12-15 04:23:16

标签: mysql ruby-on-rails ruby

我正在尝试为产品和它的产品创建一个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>

请让我知道我哪里出错了。谢谢!

1 个答案:

答案 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_keyoffers表中的product_id)具有相应的offers:< / p>

enter image description here

-

这样,您就可以访问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 %>