0

我在每个模型中都有 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

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

4

1 回答 1

2

担忧是解决办法。能够模块化您的应用程序非常重要,无论是对于 Rails 应用程序还是对于库。请注意,这种方法在与引擎挂起时也很酷。

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

配置应用程序.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

在这里你可以找到一篇很好的文章,详细解释它们。

于 2012-08-23T20:57:16.510 回答