Ruby on rails Rails 3关注模型的模块
首先,我遵循这里针对Rails的实践(好主意!): 但我遇到了一个错误:Ruby on rails Rails 3关注模型的模块,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,首先,我遵循这里针对Rails的实践(好主意!): 但我遇到了一个错误: undefined method `search' for #<Class:0x5c25ea0> app/controllers/accessories_controller.rb:6:in `index' /app/models/association.rb module Searchable extend ActiveSupport::Concern # Add a "search" scope
undefined method `search' for #<Class:0x5c25ea0>
app/controllers/accessories_controller.rb:6:in `index'
/app/models/association.rb
module Searchable
extend ActiveSupport::Concern
# Add a "search" scope to the models
def self.search (search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
class Accessory < ActiveRecord::Base
include Searchable
...
end
class AccessoriesController < ApplicationController
def index
@accessories = Accessory.search(params[:search])
...
end
end
class附件
/app/controllers/accessories\u controller.rb
module Searchable
extend ActiveSupport::Concern
# Add a "search" scope to the models
def self.search (search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
class Accessory < ActiveRecord::Base
include Searchable
...
end
class AccessoriesController < ApplicationController
def index
@accessories = Accessory.search(params[:search])
...
end
end
class AccessoriesController
好吧,再多玩弄一下,我就知道是怎么回事了
当您想要从模块(关注点)中直接修改模型时,需要将功能包装在包含的块中
我已将关注模块更改为以下内容:
module Searchable
extend ActiveSupport::Concern
included do
# Add a "search" scope to the models
def self.search (search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
end
就是这样!希望这能帮助其他人解决同样的问题 这是一个不错的解决方案,但不是最好的解决方案。当您在
ActiveSupport::Concern
上构建模块时,您可以将名为ClassMethods
的模块包装在您的关注点中,包含您的关注点的任何模块都将自动使用ClassMethods
模块进行扩展
因此,更好的解决方案是:
module Searchable
extend ActiveSupport::Concern
module ClassMethods
def search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
end
这(IMO)更清楚地表达了您的意图:在类中放置类级方法
当您的方法工作时,当您需要调用调用类上的方法时,最好使用included
方法。例如,您可以坚持您的Searchable
对象具有db-backedname
属性,如下所示。包含的included
方法将presence
验证器添加到调用类中,用于扩展该类的方法是明确分开的
module Searchable
extend ActiveSupport::Concern
def self.included(base)
base.send :validates_presence_of, :name
end
module ClassMethods
def search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
end
因此,正确的解决方案是:
module Searchable
extend ActiveSupport::Concern
module ClassMethods
def search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
end
end
在解决方案中,不在included
块中定义self.search
,这样更详细,更不明确
但是我不同意AndyV使用self.included的说法。如果您使用
ActiveSupport::Concern
,那就是要包含块语法糖,所以您应该使用它。当我调用的方法的顺序或我定义的方法很重要时,我只依赖于self.include
。很好,你自己解决了!还有几个提示:您不应该在方法定义和方法参数之间留空格。在Ruby的世界里,这不是这样做的。现在关于included
方法,它将在类的上下文中计算整个块。如果您想为类定义方法,我建议只在模块本身上定义方法,而不是将它们包装在包含的块中。感谢您提醒我们方法名称。我自己的“最佳实践”有时会不时出现在这里或那里。我理解您对包含的块所说的话。如果我定义一个非self方法,我会把它放在块之外。谢谢我希望这个答案出现在顶部。因为这是正确的解决方案