سؤال

Hi I'm new to rails and have been going in circles with this has_one association for hours. I have Products and Skins and when I create a new product via the form I'd like to use a select box to choose a skin to associate with the product.

I want to then render the product with a haml file in /skin/templates directory after having saved the name of the haml file in the templates column of the skins table.

The current error I'm getting is:

undefined method `template' for nil:NilClass

for this line in the controller:

render "/skins/templates/#{@product.skin.template}"

However I've tried other various configurations using skin_id as well and haven't been able to get past this.

Here's the code:

products_controller.rb

class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])

    if request.path != product_path(@product)
      redirect_to @product, status: :moved_permanently
    else 
      render "/skins/templates/#{@product.skin.template}"
    end
  end

  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.haml
      format.json { render json: @product }
    end
  end

  def create
    @product = Product.new(params[:product])

    respond_to do |format|
      if @product.save
        format.html { redirect_to @product, notice: 'Product was successfully created.' }
        format.json { render json: @product, status: :created, location: @product }
      else
        format.html { render action: "new" }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end
end

product.rb

class Product < ActiveRecord::Base
  attr_accessible :name, :skin
  has_one :skin
end

skin.rb

class Skin < ActiveRecord::Base
  attr_accessible :product, :name, :template
  belongs_to :product
end

_form.html.haml

= form_for @product do |f|

  - if @product.errors.any?
    #error_explanation
      %h1= "#{pluralize(@product.errors.count, "error")} prohibited this product from being saved:"
      %ul
        - @product.errors.full_messages.each do |msg|
          %li= msg

  .field
    = f.label :name
    = f.text_field :name

  = f.select :skin_id, Skin.all.collect{|t| [t.name, t.id]}

  .actions
    = f.submit 'Save'

products table

id  |     name     |         created_at         |         updated_at         
----+--------------+--------------------------------------------------------
  1 | test         | 2013-03-30 18:01:42.102505 | 2013-03-30 18:01:42.102505

skins table

 id |  name   | template |         created_at         |         updated_at         | product_id  
----+---------+----------+----------------------------+----------------------------+------------
  1 | Product | product  | 2013-03-30 20:13:26.374145 | 2013-03-30 20:13:26.374145 |             
هل كانت مفيدة؟

المحلول

product_id in skin record is empty... but looks like your product should "belongs_to" skin

1) add skin_id to your products table and remove product_id from skins table 2) change Product model

 class Product < ActiveRecord::Base
      attr_accessible :name, :sku, :skin_id
      belongs_to :skin
      validates_presence_of :skin  #add validation
    end

3) Skin model

class Skin < ActiveRecord::Base
  attr_accessible  :name, :template
  has_many :products
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top