在我的Rails应用程序中,我有步骤和问题。用户可以为任何步骤生成问题。
Step.rb
class Step < ActiveRecord::Base
has_one :question, :dependent => :destroy
accepts_nested_attributes_for :question, :allow_destroy => :true
end
Question.rb
class Question < ActiveRecord::Base
belongs_to :step
end
我使用嵌套表单生成一个问题:
<%= semantic_form_for [@project,@step] do |f| %>
<%= f.fields_for :question do |question_f| %>
<%= question_f.text_area :description %>
<% end %>
<% end %>
首先,如果用户实际在问题文本区域中输入文本,我只想创建一个新问题。如何防止步骤表格自动保存空白问题?这是我当前的步骤控制器:
class StepsController < ApplicationController
def new
@step = @project.steps.build(:parent_id=> params[:parent_id])
@step.build_question
...
end
def create
@step = @project.steps.build(params[:step])
respond_to do |format|
if @step.save
...
end
end
其次,我想在创建新问题时运行一些ruby代码。特别是,我想更新包含问题的项目的updated_at日期。我会把它放在我的控制器里?我尝试为Question模型创建一个控制器并创建create和new方法,但是在提交步骤表单时没有调用它们。
答案 0 :(得分:2)
您的第一个问题可以通过修改Step
类中的嵌套属性行来解决,如果其属性全部为空,则拒绝提交的问题,如下所示。请参阅:reject_if 下的accepts_nested_attributes_for
文档。
accepts_nested_attributes_for :question, :reject_if => :all_blank, :allow_destroy => true
你的第二个问题可以通过多种方式解决。如果始终想要在添加问题时更新项目的updated_at
(也称为“触摸”它),则可以向Question
添加回调接触项目的班级。 See this guide on callbacks
class Question < ActiveRecord::Base
belongs_to :step
has_one :project, :through => :step
after_create :touch_project
private
def touch_project
project.touch
end
end
另一方面,如果您只想在特定控制器操作的上下文中触摸问题的项目,您可以检查问题是否已创建,如果是,则触摸项目:
def create
@step = @project.steps.build(params[:step])
if @step.save
if @step.question.present?
@project.touch
end
# do other stuff for successful save
else
# handle failed save
end
end
此外,为了将来参考,如果你有两个很大程度上无关的问题,最好分别问他们。结合问题会使具有相同问题的其他人更难找到答案。