Ruby on rails 3.1 Rails相当于模型的ApplicationController

Ruby on rails 3.1 Rails相当于模型的ApplicationController,ruby-on-rails-3.1,Ruby On Rails 3.1,我知道application_controller.rb是放置所有方法的地方,您希望这些方法在所有控制器中都可用,因为它们都继承自此类。太好了 但是,模型的等价物是什么?换句话说,我想要一个可以创建两个超类的地方,我的模型将从中继承 例如,我有一个方法,通过Mysql中的REGEXP在不同的表中搜索所有CAP中的条目。我希望能够只创建一次方法,并为不同的表/模型调用它 Rails是如何做到这一点的 我想我可以创建一个从ActiveRecord::Base继承的类(就像所有模型一样),将方法放在其

我知道application_controller.rb是放置所有方法的地方,您希望这些方法在所有控制器中都可用,因为它们都继承自此类。太好了

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

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

Rails是如何做到这一点的

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

谢谢

编辑

根据塞米恩的回答,我正在编辑帖子,以显示我使用的路线。它现在可以工作了:

# 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

看看mixin,例如:

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

编辑:具体到您的示例,您正在尝试定义一个类方法。您可以在这样的混音器中执行此操作:

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

现在,当您在模型中包含Common
时,该模型的类将被扩展以包含新的类方法,并且您应该能够调用
Dvd。detect_uppercase

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

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

class Dvd
end
使用模块扩展类后,可以对该类使用不区分大小写的搜索。包含该模块将使不区分大小写的搜索成为一种实例方法,而这不是您想要的

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\u insensitive\u search.rb中,并确保在config/application.rb中有这一行:

config.autoload_paths += %W(#{config.root}/lib)
现在,您可以在任何地方使用它:

require 'case_insensitive_search'

class Dvd
  extend CaseInsensitiveSearch
end

我最不想提的是。使用有意义的名称创建多个模块。因此,与CommonModel不同的是,它具有不区分大小写的搜索等功能。

是的,在ActiveRecord的思想中加入了混合功能,以共享某种功能。从超类继承对于单表继承模式的使用是有意义的。这听起来很有希望。所以使用mixin我可以创建一个方法,根据调用它的模型来更改某些参数?我试试看。谢谢。这看起来很有希望,但是当调用
Dvd.detect\u uppercase('Dvd')
在编辑中进行更改后,最新的错误是:
NameError:uninitialized constant Common::ClassMethods
谢谢。我在试你和塞米恩的答案。塞米恩的方式不会以一种不那么麻烦的方式完成同样的事情吗?我这样问是因为我看到两者都使用扩展功能(还没有读到这方面的内容)。但是我发现您的代码中的最后一点非常混乱,即带有
self.incude(base)base.extend(ClassMethods)
的代码。这就像它在扩展自己???当模块包含在另一个类中时,调用
included
方法
base
指包含类的代码。因此,此方法使用
ClassMethods
模块中定义的方法扩展基类。我知道一开始这可能会让人困惑,但这是一种非常常见的ruby模式。Seymon的方法也会奏效-通常有不止一种方法来做这件事。不要使用
要求“model_common”
-使用
包括model common
;谢谢你,Thilo,你回答中的链接说要使用require,这就是我为什么要这么做的原因。但尝试包含ModelCommon时,会出现以下错误:
预期…/app/models/model\u common.rb来定义ModelCommon
。我以为你
需要
文件,然后
包含了
方法。这是错误的吗?这可以追溯到我的第一个想法:用这些方法创建一个文件,然后我的所有模型都将从该文件/类继承。这是正确的吗?不,你可以把你想要的任何代码放在一个文件中,而不仅仅是类。要使方法在文件外部可用,您需要定义一个模块并将方法放在其中。因此,您不能只将方法放在那里,您需要将它们包装到相同的
模块CaseInsensitiveSearch;结束这件事。您也可以在Dvd类中执行相同的
扩展不区分大小写搜索
。没有新类,也没有继承。很好的Semyon,谢谢。在我将其移动到/lib之前,它一直工作。现在我得到了未初始化的常量模型函数。请查看我上面对路由的编辑,以确保我没有做错:)对不起,我有时可能是个白痴,我在require语句中缺少了
ModelFunction
的引号。现在它工作了!所以我现在的问题是,哪种方式更好。这样或以上(Thilo的答案)。似乎如果我这样做,所有方法都将是类方法,因为
extend
功能正确吗?(请原谅我的无知,我对Rails还很陌生)。
require 'case_insensitive_search'

class Dvd
  extend CaseInsensitiveSearch
end