3

我敢肯定这是一个普遍的问题,但它让我很难过。

我在“Step”模型上有一个 has_many :through 表:

has_many :questions, :through => :question_step

该 question_step 模型在 question_id 和 step_id 字段上有存在验证器:

validates_presence_of :question_id, :step_id

还有一些复选框可以确定哪些问题属于哪个步骤

td= check_box_tag "step[question_ids][]", question.id, @step.question_ids.include?(question.id)

现在,这工作得很好,除非我想向步骤添加问题。因为 step_id 为空白,question_step 模型验证失败。如果我删除 question_step 模型中的 validate_presence_of :step_id 参数,它工作正常,但我确实确保 step_id 在那里。

我确定这是一个常见问题。...有什么想法吗?

4

2 回答 2

1

您可以检查是否存在问题和步骤对象,而不是验证步骤和问题 ID 是否存在:

validates_presence_of :question, :step

如果这不起作用,您应该考虑删除应用程序级别的验证并改为添加数据库约束,您只需在迁移中向列添加非空约束:

def up
  change_column question_steps, :question_id, :integer, :null => false
  change_column question_steps, :step_id,     :integer, :null => false
end
于 2013-03-30T01:40:05.453 回答
0

我有一个非常相似的问题。根据这个问题,出现了竞争条件。

在我的控制器的创建操作中,我决定首先使用排除关联参数的参数来创建没有关联的主模型。然后使用关联参数更新模型。

所以在你的情况下它可能是

def create
  @step = Step.create(create_params)
  @step.update_attributes(association_params) unless @step.errors.any?
  respond_to do |format|
    if @step.errors.empty?
      format.html #etc..
    else
      format.html#...etc..
    end
  end
end

private
def create_params
  perm_params = step_params
  perm_params.delete :question_ids
  perm_params
end
def association_params
  params.require(:step).permit(question_ids: [])
end
def step_params
  params.require(:step).permit(:name, :other_attributes, question_ids: [])
end

这样您就不必将验证移动到您的数据库中。您仍将在更新方法中使用正常的 step_params。

params 方法可能会被干掉一点,我想知道为什么我需要为在 rails 3 中简单工作的东西而大惊小怪,但它现在对我有用。

于 2014-10-09T20:31:11.520 回答