我正在尝试将大型模型拆分为多个文件以进行逻辑组织。所以我有两个文件:
model1.rb
class Model1 < ActiveRecord::Base
before_destroy :destroying
has_many :things, :dependent=>:destroy
def method1
...
end
def method2
...
end
end
require 'model1_section1'
model1_section1.rb
class Model1
def method3
...
end
def self.class_method4
...
end
end
但是当应用加载,并且有对Model1.class_method4的调用时,我得到:
undefined method `class_method4' for #<Class:0x92534d0>
我也尝试过这个要求:
require File.join(File.dirname(__FILE__), 'model1_section1')
我在这里做错了什么?
答案 0 :(得分:9)
我知道我的回答有点晚了,但我刚刚在我的一个应用程序中做了这个,所以我想发布我用过的解决方案。
让我们这是我的模特:
class Model1 < ActiveRecord::Base
# Stuff you'd like to keep in here
before_destroy :destroying
has_many :things, :dependent => :destroy
def method1
end
def method2
end
# Stuff you'd like to extract
before_create :to_creation_stuff
scope :really_great_ones, #...
def method3
end
def method4
end
end
您可以将其重构为:
# app/models/model1.rb
require 'app/models/model1_mixins/extra_stuff'
class Model1 < ActiveRecord::Base
include Model1Mixins::ExtraStuff
# Stuff you'd like to keep in here
before_destroy :destroying
has_many :things, :dependent => :destroy
def method1
end
def method2
end
end
和:
# app/models/model1_mixins/extra_stuff.rb
module Model1Mixins::ExtraStuff
extend ActiveSupport::Concern
included do
before_create :to_creation_stuff
scope :really_great_ones, #...
end
def method3
end
def method4
end
end
由于ActiveSupport::Concern
给你的额外清洁度,它完美地运作。希望这能解决这个老问题。
答案 1 :(得分:5)
这篇文章很好地提出了解决这个问题的方法:
http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
答案 2 :(得分:2)
我知道我迟到了,但在试图弄清楚如何做到这一点时,我偶然发现了这个问题。
我认为类重新打开的原因在示例代码中没有按预期工作的答案是该类最初被定义为:
(在model1.rb中)
class Model1 < ActiveRecord::Base
然后重新打开: (在model1_section1.rb中)
class Model1
即。第二个定义是缺少继承的类。
我使用了单独的.rb文件来分割我的巨大模型,而且它们对我来说很有效。虽然我承认我使用了include和更像这样的东西:
(在workcase.rb中)
class Workcase < ActiveRecord::Base
include AuthorizationsWorkcase
include WorkcaseMakePublic
include WorkcasePostActions
after_create :set_post_create_attributes
# associations, etc
# rest of my core model definition
end
(在workcase_make_public.rb中)
module WorkcaseMakePublic
def alt_url_subject
self.subject.gsub(/[^a-zA-Z0-9]/, '_').downcase
end
# more object definitions
end
class Workcase < ActiveRecord::Base
def self.get_my_stuff
do_something_non_instance_related
end
# more class definitions
end
这使我能够将类和对象方法合并到每个包含的.rb文件中。唯一的警告(因为我没有使用关注扩展)是从模块对象方法中访问类常量需要使用类名限定常量(例如Workcase :: SOME_CONST)而不是直接允许如果在主文件中调用。
总的来说,这种方法似乎需要对代码进行最少量的重写,以便将事物变成易于管理的代码块。
也许这不是真正的'Rails方式',但它确实在我的特定情况下运行良好。
答案 3 :(得分:1)
有一个叫做modularity的整洁宝石,可以完全满足您的需求。
关于如何正确拆分它们的一个很好的指南是gem-session。
答案 4 :(得分:1)
如果你真的试图将一个类拆分成两个文件(类似于C#中的部分类),我不知道这样做的红宝石友好方式。
然而,通过Mixins获得具有相当功能(包括大量方法)的类的一种常见方法。模块可以混合到一个类中,它们的方法实际上包含在类中。