Rails 3 - reject_if如何与构建一起工作?

时间:2014-01-10 06:58:34

标签: ruby-on-rails ruby nested-forms

使用Rails 3.1& Ruby 1.9.2。

我在问题和答案模型之间有一个has_many关联。问题模型有这一行:

accepts_nested_attributes_for :answers, :reject_if => 
        lambda { |n| n[:content].blank? }, :allow_destroy => true

我的观点有点复杂,只需说它返回一个问题数组,其中每个问题可能有一个0到5个答案之间的嵌套数组。我确信这部分工作正常。


在我的控制器中,我运行以下代码来构建和保存问题&答案:

def create_questions
   params[:question].each do |q|
     new_question = Question.new(q)

     ...

     if q[:answers] != nil # this only solves the problem of 
                           # a question having 0 answers 
       q[:answers].each do |a|
         new_question.answers.build(a)
       end
    end

    new_question.save
  end
end

我的问题是我用空白内容保存答案。我认为answers.build覆盖了reject_if,但我不确定。我很清楚,我可以使用一百万种解决方法来解决这个问题,但是传统的和最短的(代码方式)方式是什么?

2 个答案:

答案 0 :(得分:1)

accept_nested_attributes_for方法用于直接输入嵌套模型的字段。我的意思是你只需要在问题哈希中包含:answers_attributes。它应该在视图中完成。但是我不确定你是如何处理视图所以我要替换

if q[:answers] != nil # this only solves the problem of a question having 0 answers 
   q[:answers].each do |a|
     new_question.answers.build(a)
   end
end

q[:answers_attributes] = q.delete(:answers)

或者您只需将视图中的:answers更改为:answers_attributes即可。并从控制器中删除条件部分。

注意您还需要answers_attributes来建模attr_accessible

答案 1 :(得分:0)

accepts_nested_attributes_for自动处理params。

如果您的表单中有

<%= form_for @question do |f| %>

在里面你有

<%= f.fields_for :answers do |f| %>

然后,在创建问题时创建答案的逻辑已经存在。检查字段的名称是否应与question[][answers_attributes][content]类似。

在你的控制器中,你只需要这样做:

new_question = Question.new(q)

这将使用reject_if块为您创建嵌套问题。

如果您手动创建答案,那么您也有责任拒绝答案。