使用has_many关联结果创建对象不能为空

时间:2013-08-10 15:05:56

标签: ruby-on-rails

我有以下关联和相关的控制器,在我的表单中我正在添加每个字段应该是。但是当我尝试创建一个Item时,我仍然会收到错误评级项目不能为空。我正在使用 Rails 4.0 。我为此广泛搜索过,但仍然无法找到我做错的事。三江源!

class Item < ActiveRecord::Base
  has_many :ratings, dependent: :destroy
  accepts_nested_attributes_for :ratings, :allow_destroy => true
  validates :name , :length => { minimum: 3 }
  validates :category , :length => { minimum: 3 }
end

class Ratings < ActiveRecord::Base
  belongs_to :user
  belongs_to :item
  default_scope -> { order('created_at DESC') }
  validates :user_id, :presence => true
  validates :item_id, :presence => true
  validates_numericality_of :rating, :greater_than_or_equal_to => 0
  validates_numericality_of :rating, :less_than_or_equal_to => 5

end

class ItemsController < ApplicationController
  before_action :set_item, only: [:show]
  before_action :user_signed_in?, only: :create

  def create
    @item = Item.new
    @rating = @item.ratings.build
    @rating.comment = params[:item][:ratings_attributes][:comment]
    @rating.rating = params[:item][:ratings_attributes][:rating]
    @rating.user_id = current_user.id

    @item.name = params[:item][:name]
    @item.url = params[:item][:url]
    @item.full_address = params[:item][:full_address]
    @item.city = params[:item][:city]
    @item.country = params[:item][:country]
    @item.category = params[:item][:category]

    respond_to do |format|
      if @item.save
        #TODO create rating here (First rating of an Item)
        flash[:success] = "Welcome to inmyopnion"
        format.html { redirect_to @item, notice: 'Item was successfully created.' }
        format.json { render action: 'show', status: :created, location: @item }
      else
        format.html { render action: 'new' }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  def new
    @item = Item.new
  end

  def show
  end

  def destroy
  end

  private

  def set_item
    @item = Item.find(params[:id])
  end

  def item_params
    params.require(:item).permit(:name, :url, :full_address, :city, :country, :category, :ratings_attributes => [:rating, :comment])
  end

  def user_signed_in?
    #TODO: should display should sign in to rate an item
    redirect_to(root_url) unless signed_in?
  end
end

3 个答案:

答案 0 :(得分:1)

简化您的控制器!由于您允许使用nested_attributes,因此这应该足够了:

@item = Item.create(params[:item])

问题可能是由@rating对象未保存引起的。

答案 1 :(得分:0)

我通过评论

中的以下给定行来完成它
class Ratings < ActiveRecord::Base
validates :item_id, :presence => true

但我的关联rspec test失败并保存Ratings而没有item_id。 其余代码类似于我发布的

@item = Item.create(params[:item])

给出ActiveModel::ForbiddenAttributesError

答案 2 :(得分:0)

很好地使用nested_attributes的代码和文档,最后也是一个验证关联的工作程序。这些是下面列出的变化(标记在** .... **之间)

class Item < ActiveRecord::Base
  has_many :ratings, dependent: :destroy, **inverse_of: :item**
  accepts_nested_attributes_for :ratings, :allow_destroy => true
  validates :name , :length => { minimum: 3 }
  validates :category , :length => { minimum: 3 }
end

class Ratings < ActiveRecord::Base
  belongs_to :user
  belongs_to :item, **inverse_of: :ratings**
  default_scope -> { order('created_at DESC') }
  validates :user_id, :presence => true
  validates_presence_of :item
  validates_numericality_of :rating, :greater_than_or_equal_to => 0
  validates_numericality_of :rating, :less_than_or_equal_to => 5
end

仍然无法从@item = Item.create(params[:item])创建一个仍然给出一个 @BroiSatse建议的ActiveModel::ForbiddenAttributesError以及不应该是nested_attributes的文档

问题可能在

class ItemsController < ApplicationController

def item_params
    params.require(:item).permit(:name, :url, :full_address, :city, :country, :category, :ratings_attributes => [:rating, :comment])
  end
如果找到解决方案,

也会努力解决这个问题并发布答案。