在哪里放置在多个模型中找到的通用代码?
我有两个包含相同方法的模型:
def foo
# do something
end
我应该把它放在哪里?
我知道公共代码位于 Rails 应用程序的 lib
目录 中。
但是,如果我将其放入 lib
中名为“Foo
”的新类中,并且我需要将其功能添加到我的两个 ActiveRecord 模型
,我是否这样做:
class A < ActiveRecord::Base
includes Foo
class B < ActiveRecord::Base
includes Foo
然后 A
和 B
都将包含 foo
方法,就像我在每个方法中定义了它一样?
I have two models that contain the same method:
def foo
# do something
end
Where should I put this?
I know common code goes in the lib
directory in a Rails app.
But if I put it in a new class in lib
called 'Foo
', and I need to add its functionality to both of my ActiveRecord models
, do I do that like this:
class A < ActiveRecord::Base
includes Foo
class B < ActiveRecord::Base
includes Foo
and then both A
and B
will contain the foo
method just as if I had defined it in each?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
创建一个模块,您可以将其放入
lib
目录中:然后您可以在每个模型类中
包含
该模块:A
和B
模型现在将定义一个foo
方法。如果您遵循 Rails 命名约定,使用模块名称和文件名称(例如 foo.rb 中的 Foo 和 foo_bar.rb 中的 FooBar),那么 Rails 将自动为您加载该文件。否则,您将需要使用
require_dependency 'file_name'
加载您的 lib 文件。Create a module, which you can put in the
lib
directory:You can then
include
the module in each of your model classes:The
A
andB
models will now have afoo
method defined.If you follow Rails naming conventions with the name of the module and the name of the file (e.g. Foo in foo.rb and FooBar in foo_bar.rb), then Rails will automatically load the file for you. Otherwise, you will need to use
require_dependency 'file_name'
to load your lib file.您实际上有两个选择:
如果共享功能不是每个类的核心,但适用于每个类,则使用#1。例如:
如果共享功能对于每个类和 A 和 A 都是通用的,则使用#2。 B 具有天然的关系:
You really have two choices:
Use #1 if the shared functionality is not core to each class, but applicable to each class. For example:
Use #2 if the shared functionality is common to each class and A & B share a natural relationship:
我是这样做的...首先创建 mixin:
然后将其混合到需要它的每个模型中:
这几乎很漂亮!
为了完成这个例子,虽然它与问题无关,但这是我的 slug 模型:
Here's how I did it... First create the mixin:
Then mix it into every model that needs it:
It's almost pretty!
To complete the example, though it's irrelevant to the question, here's my slug model:
一种选择是将它们放在新目录中,例如
app/models/modules/
。然后,您可以将其添加到 config/environment.rb 中:这将需要该目录中的每个文件,因此如果您将如下所示的文件放入模块目录中:
然后你就可以在你的模型中使用它,因为它会自动加载:
这种方法比将这些 mixins 放在
lib
目录中更有组织性,因为它们位于使用它们的类附近。One option is to put them in a new directory, for example
app/models/modules/
. Then, you can add this toconfig/environment.rb
:This will
require
every file in in that directory, so if you put a file like the following in your modules directory:Then you can just use it in your models because it will be automatically loaded:
This approach is more organized than putting these mixins in the
lib
directory because they stay near the classes that use them.如果您需要 ActiveRecord::Base 代码作为常用功能的一部分,那么使用抽象类也可能很有用。比如:
就这么简单。另外,如果代码与 ActiveRecord 无关,请查找
ActiveSupport::Concerns
作为更好的方法。If you need ActiveRecord::Base code as a part of your common functionalities, using an abstract class could be useful too. Something like:
As simple as that. Also, if the code is not ActiveRecord related, please find
ActiveSupport::Concerns
as a better approach.正如其他人提到的, include Foo 是做事的方式......但是,它似乎无法通过基本模块为您提供所需的功能。以下是许多 Rails 插件除了新实例方法之外添加类方法和新回调的形式。
As others have mentioned include Foo is the way to do things... However it doesn't seem to get you the functionality you want with a basic module. The following is the form a lot of Rails plugins take to add class methods and new callbacks in addition to new instance methods.