【问题标题】:Accepts Nested Attributes & Filters接受嵌套属性和过滤器
【发布时间】:2012-09-19 14:20:45
【问题描述】:

假设我有两个模型;发表评论

class Post < ActiveRecord::Base
  has_many :comments
  accepts_nested_attributes_for :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post

  before_save :do_something

  def do_something
    # Please, let me do something!
  end
end

我有一个 Post 表单,其中包含 cmets 字段。一切都按预期工作,除了过滤器。通过上述配置,评论上的 before_save 过滤器不会被触发。

您能解释一下原因吗?我该如何解决这个问题?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.2


    【解决方案1】:

    在这种情况下,Rails 不会单独实例化和保存 cmets。您最好在 Post 模型中添加一个回调来处理嵌套 cmets:

    class Post < AR::Base
      before_save :do_something_on_comments
      def do_something_on_comments
        comments.map &:do_something
      end
    end
    

    【讨论】:

    • 感谢您的回答。但是假设我想避免这种技术。有没有其他方法可以达到完全相同的结果?也许在关联上有一些参数?类似“has_many :cmets, :autosave => true”或“accepts_nested_attributes_for :cmets, :touch => true”?
    【解决方案2】:

    根据 Bryan Helmkamp 的说法,使用表单对象模式比使用accepts_nested_attributes_for 更好。看看7 Patterns to Refactor Fat ActiveRecord Models

    也许你可以做这样的事情?

    class NewPost
      include Virtus
    
      extend ActiveModel::Naming
      include ActiveModel::Conversion
      include ActiveModel::Validations
    
      attr_reader :post
      attr_reader :comment
    
      # Forms are never themselves persisted
      def persisted?
        false
      end
    
      def save
        if valid?
          persist!
          true
        else
          false
        end
      end
    
    private
    
      def persist!
        @post = Post.create!
        @comment = @post.comment.create!
      end
    end
    

    do_something 在您创建评论时会被调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多