Rails相当于ApplicationController的模型

时间:2012-02-13 14:14:02

标签: ruby-on-rails-3.1

我知道application_controller.rb是放置所有控件的所有方法等的地方,因为它们都从这个类继承。大。

但是模特的等价物是什么?换句话说,我想要一个可以创建我的模型将继承的几个超类的地方。

例如,我有一个方法,通过Mysql中的REGEXP在不同的表中搜索所有CAPS中的条目。我希望能够只创建一次方法,并为不同的表/模型调用它。

Rails的做法是什么?

我以为我可以创建一个从ActiveRecord :: Base继承的类(就像所有模型一样),将方法放在那里,然后从该类继承我的所有模型。但是我认为肯定会有更好的方法。

感谢。

修改

Per Semyon的回答我正在编辑帖子以显示我正在使用的路线。它现在有效:

# models/dvd.rb
require 'ModelFunctions'
class Dvd < ActiveRecord::Base
    extend ModelFunctions
    ...
end

# lib/ModelFunctions.rb
module ModelFunctions
    def detect_uppercase(object)
        case object
        ...
        where("(#{field} COLLATE utf8_bin) REGEXP '^[\w[:upper:]]{5,}' ").not_locked.reorder("LENGTH(#{field}), #{table}.#{field} ASC")
    end
end

在config / application.rb

config.autoload_paths += %W(#{config.root}/lib)

2 个答案:

答案 0 :(得分:2)

看看mixins,例如:

http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html

在Rails应用程序中,您可以在lib目录中创建一个定义方法的模块,然后在模型中include创建一个模块。

编辑:要特定于您的示例,您正在尝试定义类方法。你可以在这样的mixin中做到这一点:

module Common
  module ClassMethods
    def detect_uppercase(object)
      case object
      when 'dvd'
          field = 'title'
      ... 
      end    
      where("(#{field} COLLATE utf8_bin) REGEXP '^[\w[:upper:]]  {5,}').not_locked.reorder('LENGTH(title), title ASC')"
    end
  end

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

现在当您在模型中include Common时,该模型的类将扩展为包含新的类方法,您应该能够调用Dvd.detect_uppercase

答案 1 :(得分:1)

将可重用方法放在Dvd类旁边的某个模块中。您可以稍后在单独的文件中将其移动。

# app/models/dvd.rb
module CaseInsensitiveSearch
  def case_insensitive_search(field, value)
    # searching field for value goes here
  end
end

class Dvd
end

使用模块扩展类后,您可以在类上使用case_insensitive_search。包含该模块将使case_insensitive_search成为一种不是您想要的实例方法。

class Dvd
  extend CaseInsensitiveSearch
end

Dvd.case_insensitive_search("title", "foo")

当然你可以在Dvd类中使用它。

class Dvd
  def self.search(query)
    case_insensitive_search("title", query)
  end
end

Dvd.search("foo")

现在,当您确定它有效时,您可能希望将其移动到单独的文件中并在多个类中使用它。将它放在lib / case_insensitive_search.rb中,并确保在config / application.rb中有这一行:

config.autoload_paths += %W(#{config.root}/lib)

现在您可以在任何想要使用它的地方使用它:

require 'case_insensitive_search'

class Dvd
  extend CaseInsensitiveSearch
end

我想提出的最后一件事。用有意义的名称创建多个模块。因此,而不是CommonModel有CaseInsensitiveSearch等等。