1

我有一个创建操作,它试图一次性创建评级和程序:

  def create
    @rating = current_user.ratings.create(params[:rating])
    @rating.create_programme(params[:programme])
    redirect_to ratings_path
  end

在此代码中,评分属于用户和程序以及用户

  has_many :ratings
  has_many :programmes, :through => :ratings

和一个程序

  has_many :users, :through => :ratings
  has_many :ratings

当我在 RatingsController 中调用上面的创建操作时,由于某种原因,程序没有被保存为由 @rating 拥有。所以,如果我打电话给例如:

rating.programme.channel 

在视图中的评级上,它告诉我该程序是一个 nil 对象。但是,该程序已保存完好 - 只是尚未保存的关联。我敢肯定这是一个非常基本的东西,但我无法弄清楚。有人可以指出我正确的方向吗?

谢谢

4

4 回答 4

2

回答您的问题以帮助使代码更清洁:

def create
  @rating = Rating.new(params[:rating])
  @rating.user      = curent_user
  @rating.programme = Programme.find_or_create_by_title(params[:programme])
  @rating.save

  redirect_to ratings_path
end

首先,您为标题调用 find_or_create 然后保存它,但记录将在那里创建,因此保存根本不做任何事情。其次,虽然关联代理在轻松创建相关对象方面很酷,但在像您这里这样更复杂的关系中它们可能会变得非常多毛,并使代码更难阅读。

因此,与其使用关联代理来创建记录,不如直接分配更好。它更容易一目了然地知道发生了什么以及信息来自哪里,并且不需要在那里进行丑陋的合并调用。它有点长,但我认为它更容易一目了然。

最后,您可能不需要@programme作为独立的实例变量,因为您可以从@rating.programme视图中轻松访问该对象。在大多数情况下,最好传递尽可能少的实例变量,尤其是当对象具有易于访问的直接关系时。在这种情况下尤其如此,因为您根本没有渲染模板。

于 2009-02-07T19:48:13.483 回答
0

您的代码看起来正确。试试这个。在点击此创建操作后立即进入您的脚本/控制台并查看发生了什么。类型:

Rating.last

它应该返回刚刚创建的评级。在输出中查找user_idprogramme_id查看它们是否已设置。如果是,那么您在其他地方就有错误。也许您没有查看您认为自己的评级或其他内容。

于 2009-02-06T17:05:19.303 回答
0

好吧,您正在尝试从孩子创建父母(评级属于程序,对吗?)。我认为这行不通。

Programme.ratings.create 会起作用。

于 2009-02-06T17:27:14.753 回答
0

我的创建操作可以正常使用以下内容。如果有人能让我知道是否有更优雅的方法可以让它工作,将不胜感激:)

  def create
    @programme = Programme.find_or_create_by_title(params[:programme])
    @programme.save
    @rating = current_user.ratings.create!(params[:rating].merge(:programme_id => @programme.id))
    redirect_to ratings_path
  end

安迪

于 2009-02-07T14:57:08.533 回答