我正在使用Ruby on Rails 3.0.9,我试图从内部帮助器,控制器,模型和视图文件中调用一些方法。我想要做的是创建一个库,在我的应用程序内部构建\ standardize命名约定,以便我可以使用\运行如下所示:
standardized_name = standardize_name(Article)
您有什么建议?
P.S。:我听说过mixin,但我应该如何在我的情况下使用它们?此外,我不想在每个需要使用它的类中声明包含mixin(也就是说,我希望在我的所有应用程序类中都包含一个包含mixin的“唯一”语句。)
答案 0 :(得分:6)
可以在Rails MVC的所有层中访问的类似库是I18n。您可以使用I18n.t调用translate方法,而视图和控制器层中有一个辅助方法,因此您不需要每次都输入整个“I18n.t”。
我们可以遵循I18n的做法。您可以在应用程序的lib目录中创建一个模块。确保更新application.rb以便加载模块。在application.rb中查找此评论:
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
显然,如果您取消注释autoload_paths行,请将“extras”更改为“lib”。
这是一个示例模块lib / Karate.rb:
module Karate
class << self
def punch(grunt)
puts "#{grunt}! *punch*"
end
end
end
现在您可以在应用程序的任何位置调用它:
Karate.punch("boom")
# => boom! *punch*
如果您想在View和Controller层中使用辅助方法,只需在application_controller.rb中添加一个方法:
def punch(grunt)
Karate.punch(grunt)
end
并将此方法声明为辅助方法(也在application_controller.rb中),如下所示:
helper_method :punch
但是请确保你真的需要这个库。我没有质疑你的理由,因为它不会回答你的主要问题。我认为您应该在代码中练习您的命名约定,如果必须,请将其添加到README中,或者向您的团队发送电子邮件。此外,Rails和Ruby已经有了命名约定,所以一定要了解它。
答案 1 :(得分:4)
根据您的使用情况,您可以采用其中一种方法,而不是将方法附加到其作用于的对象上。那么您不需要在任何想要使用它的地方都包含standardize_name
方法;你只需将它集中在它适用的对象上:
如果您的standardize_name
方法仅将ActiveRecord模型作为参数,请考虑将其放在模块中(例如在lib/standardizable.rb
中)并将其扩展到ActiveRecord::Base
(或其他一些类)所有域类的父级):
module Standardizable
def standardized_name
# in here, self will be the model *class*,
# so the following will return "Article" if you
# extended the module into the Article class:
self.name
end
end
# include the mixin in all ActiveRecord models:
ActiveRecord::Base.extend Standardizable
或者,如果您不想将其包含在所有模型中,只需将模块包含在您希望standardized_name
可用的各个类中:
class Article < ActiveRecord::Base
extend Standardizable
end
使用以下两种方法,您将能够使用如下方法:
standardized_name = Article.standardized_name
如果您更愿意在模型类的实例上使用该方法,只需将上例中的extend
更改为include
:
module Standardizable
def standardized_name
# in here, self will be the model object *instance*,
# so the following will return "Article" if you
# included the module into the Article class:
self.class.name
end
end
# include the mixin in all ActiveRecord models:
ActiveRecord::Base.send(:include, Standardizable)
然后用法如下:
article = Article.new
standardized_name = article.standardized_name
在Rails 3中包含这两种方法的好方法是使用ActiveSupport::Concern
:
module Standardizable
extend ActiveSupport::Concern
module ClassMethods
def standardized_name
self.name
end
end
module InstanceMethods
def standardized_name
self.class.standardized_name
end
end
end
ActiveRecord::Base.extend Standardizable
然后,您可以使用class和instance方法获取标准化名称:
standardized_name_from_class = Article.standardized_name
article = Article.new
standardized_name_from_instance = article.standardized_name