【问题标题】:Use modules functions in Models in Rails 3在 Rails 3 中的模型中使用模块函数
【发布时间】:2012-08-23 19:22:25
【问题描述】:

我在每个模型中都有 4 个常用功能:

#Returns TRUE or FALSE depending on whether the column could be null or not
def self.null?(column)
  columns_hash[column].null
end

#Custom delete function to change a state (deleted is a field)
def custom_delete
  deleted = true
  save
end

def str_created_at(format = "%d/%m/%Y %I:%M %p")
  return created_at.in_time_zone.strftime(format)
end

def str_updated_at(format = "%d/%m/%Y %I:%M %p")
  return updated_at.in_time_zone.strftime(format)
end

我试图将这 4 个函数(其中 1 个是抽象的:null?)移动到一个模块,但没有成功:

#config/application.rb
config.autoload_paths += Dir["#{config.root}/lib/**/"]

#app/models/post.rb
class Post < ActiveRecord::Base
    include BaseModel
    default_scope where(:deleted => false)
end

#lib/base_model.rb
module BaseModel

    def self.included(base)
        base.extend ClassMethods
    end

    module InstanceMethods

        def custom_delete
            deleted = true
            save
        end

        def str_created_at(format = "%d/%m/%Y %I:%M %p")
            return created_at.in_time_zone.strftime(format)
        end

        def str_updated_at(format = "%d/%m/%Y %I:%M %p")
            return updated_at.in_time_zone.strftime(format)
        end
    end 

    module ClassMethods
        include BaseModel::InstanceMethods

        def self.null?(column)
            columns_hash[column].null
        end
    end

end

在 Rails 控制台中:

> Post.null?("title")
> NoMethodError: undefined method 'null?' for #<Class:0x3f075c0>
> post = Post.first
> post.str_created_at
> NoMethodError: undefined method 'str_created_at' for #<Post:0x2975190>

有没有办法让这些功能正常工作?我在 Stackoverflow 上找到了这段代码,但似乎没有用,至少 Rails3 没有

我希望能够仅用 1 行添加这些功能: 包括 BaseModel

所以我也可以将它添加到其他模型中。

【问题讨论】:

    标签: ruby-on-rails-3 module dry


    【解决方案1】:

    问题是解决方案。能够模块化您的应用程序非常重要,无论是对于 Rails 应用程序还是对于库。请注意,这种方法在使用 Engine 时也很酷。

    对于模型和控制器,必须将关注点放在关注点文件夹中。请注意不要过多地使用它们。您必须主要在类之间共享功能以及想让模型变瘦时使用它。在最后一种情况下等待它真的很大,否则关注将成为垃圾目录,您将失去它的作用。

    配置应用程序.rb

    您可以在此处了解如何组织模型和控制器关注点。

    module YourApp
      class Application < Rails::Application
        config.autoload_paths += %W(
          #{config.root}/app/controllers/concerns
          #{config.root}/app/models/concerns
        )
      end
    end
    

    创建关注点

    您可以使用ActiveSupport::Concern 类定义您的关注点。它简化了“包含”阶段(您不必使用 base 作为前缀),它会自动加载模块 ClassMethod 内部的类方法。

    这里有一个变化的例子。

    class Message < ActiveRecord::Base
      include Trashable
    end
    
    module Trashable
      extend ActiveSupport::Concern
    
      included do
        field :new
      end
    
      module ClassMethods
        # some class methods
      end
    
      # some instance methods
      end
    

    在这里你可以找到一个很好的article,它可以更详细地解释它们。

    【讨论】:

    • 感谢您的链接,它解决了问题。太感谢了!现在我可以继续使用 DRY on Rails 了 :)
    猜你喜欢
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    相关资源
    最近更新 更多