【问题标题】:Nested Form Model - Run Condition Action嵌套表单模型 - 运行条件操作
【发布时间】:2013-11-24 21:54:29
【问题描述】:

在我的 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 方法,但在提交步骤表单时没有调用它们。

【问题讨论】:

    标签: ruby-on-rails forms activerecord controller


    【解决方案1】:

    您的第一个问题可以通过修改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
    

    另外,为了将来参考,如果您有两个基本不相关的问题,最好分开提问。组合问题会使其他有相同问题的人更难找到答案。

    【讨论】:

    • 这是完美的,谢谢!我从来不知道 reject_if 并且肯定会在我的应用程序的其他区域使用它。
    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    相关资源
    最近更新 更多