【问题标题】:avoiding code duplication in Rails 3 models避免 Rails 3 模型中的代码重复
【发布时间】:2011-12-01 01:48:08
【问题描述】:

我正在开发一个 Rails 3.1 应用程序,其中有许多不同的类似枚举的模型存储在数据库中。这些模型以及相关的控制器和视图中有很多相同的代码。我已经通过共享父控制器类和 Rails 3 中的新视图/布局继承解决了控制器和视图的代码重复问题。

现在我正在尝试解决模型中的代码重复问题,但我陷入了困境。我的枚举模型之一的示例如下:

class Format < ActiveRecord::Base

  has_and_belongs_to_many :videos

  attr_accessible :name

  validates :name, presence: true, length: { maximum: 20 }

  before_destroy :verify_no_linked_videos

  def verify_no_linked_videos
    unless self.videos.empty?
      self.errors[:base] << "Couldn't delete format with associated videos."
      raise ActiveRecord::RecordInvalid.new self
    end
  end

end

我有四五个其他类的代码几乎相同(关联声明是唯一的区别)。我已经尝试使用它们都包含的共享代码创建一个模块(这看起来像 Ruby 方式),但是大部分重复代码依赖于 ActiveRecord,所以我试图在模块中使用的方法(验证,attr_accessible等)不可用。我知道 ActiveModel,但这并没有让我一路走好。

我也尝试过创建一个通用的、非持久的父类,它是 ActiveRecord::Base 的子类,但我看到的所有实现此目的的代码都假定您不会有非持久类的子类确实持续存在。

对于如何最好地避免在许多不同的枚举模型中重复这些相同的代码行有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    我找到了 Rails 3 模型的代码共享解决方案,所以我想与其他人分享。事实证明,ActiveModel 确实拥有我需要的一切(至少到目前为止)。我使用ActiveSupport::ConcernActiveModel::ValidationsActiveModel::MassAssignmentSecurity 创建了一个枚举模块,并将该模块包含在我的每个枚举模型中:

    module Enum
    
      extend ActiveSupport::Concern
    
      include ActiveModel::Validations
      include ActiveModel::MassAssignmentSecurity
    
      included do
    
        attr_accessible :name
    
        validates :name, presence: true, length: { maximum: 20 }
    
        before_destroy :verify_no_linked_videos
    
        private
    
        def verify_no_linked_videos
          unless self.videos.empty?
            self.errors[:base] << "Couldn't delete object with associated videos."
            raise ActiveRecord::RecordInvalid.new self
          end
        end
    
      end
    
    end
    

    Rails 3 团队将非数据库代码从 ActiveRecord 提取到 ActiveModel 中的方式确实非常巧妙!以下链接有助于巩固我对如何使用这些东西的理解:

    http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/

    http://asciicasts.com/episodes/237-dynamic-attr-accessible

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-16
      • 2014-03-07
      • 1970-01-01
      • 2017-09-12
      • 2021-11-07
      • 2023-03-24
      相关资源
      最近更新 更多