Ruby on rails Rails模型分为多个定义
在我的几个rails模型中,我有一些逻辑,我想将它们拆分成单独的文件 具体来说,这是这些模型特有的逻辑,而不是模型之间共享的逻辑。在这种情况下,我意识到担忧/混杂和问题 因为我们在这里讨论的是Ruby,所以看起来应该有多个类定义。例如:Ruby on rails Rails模型分为多个定义,ruby-on-rails,ruby,ruby-on-rails-3,activesupport,Ruby On Rails,Ruby,Ruby On Rails 3,Activesupport,在我的几个rails模型中,我有一些逻辑,我想将它们拆分成单独的文件 具体来说,这是这些模型特有的逻辑,而不是模型之间共享的逻辑。在这种情况下,我意识到担忧/混杂和问题 因为我们在这里讨论的是Ruby,所以看起来应该有多个类定义。例如: # in app/models/user.rb class User < ActiveRecord::Base ... end # in app/lib/integrations/ext/user.rb class User ... end 但
# in app/models/user.rb
class User < ActiveRecord::Base
...
end
# in app/lib/integrations/ext/user.rb
class User
...
end
但这会给其他gem带来问题(例如,加载用户模型时未加载designe)
这有什么好办法吗?还是我在这里出了问题?利用Ruby的开放类是Rails之外的常见习惯用法。将以下内容添加到
config/application.rb
config.autoload_paths += Dir["#{config.root}/lib"]
module MyNamespace
module UserRepo
extend self
def create_admin!(attrs)
# complex logic to setup admin user account here
deliver_confirmation_email!(newly_created_user)
end
private
def deliver_confirmation_email!(user)
# sends email off to user represented by this class instance
end
end
end
这将根据Rails的要求从integrations/ext
自动加载类。(DHH的要点恰好包括了app/model/concerns
文件)
(我更改了我的自动加载以匹配@denis.pelin的内容。我错过了
integrations/
在lib/
中的内容,因此上述内容应足以自动加载)。在我的一个应用程序中,我在application.rb
中有未注释的自动加载行:
# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
lib目录中的某些模块:
# lib/some_module.rb
module SomeModule
def some_method
end
end
并包含在模型中:
# app/models/user.rb
class User < ActiveRecord::Base
include SomeModule
end
#app/models/user.rb
类用户
现在用户实例有了
一些方法
如果我理解正确的话,你要做的是将仍然特定于a模型的代码移出该模型(多个模型之间并不常见,这表明混入是正确的方法)使其保持“精简”;实际上只是看起来“偏离”模型中存在的代码
当我看到模型中的代码变得有点太复杂,或者直接在模型中包含看起来错误的任务时,我会在lib/
中创建一个文件。对于(简化的)示例,给定如下模型
class User < ActiveRecord::Base
def self.create_admin!(attrs)
# complex logic to setup admin user account here
newly_created_user.deliver_confirmation_email!
end
def deliver_confirmation_email!
# sends email off to user represented by this class instance
end
end
现在,在我的中,在我的控制器中创建操作,而不是调用
User.create_admin!(params[:user])
我会打电话给你
MyNamespace::UserRepo::create_admin!(params[:user])
MyNamespace::UserRepo
负责管理管理员帐户的用户
记录发生的情况,使我的控制器操作和模型保持整洁。由于这种分离,测试MyNamespace::UserRepo
也更容易
这仍然不能解决让rails需要所需代码的问题,但可能为您试图实现的目标提供了另一种解决方案。自动加载仅在引用类时加载类。在mixin/concern的情况下(在本例中我避免使用),该类在模型中被引用,因此它被加载。在我的例子中,我试图简单地打开类备份(原始模型定义没有对扩展的引用)。很抱歉,不清楚您如何使用lib/integrations/ext
中的User
类<代码>…
作为这两个类的主体中的唯一内容,并不能真正帮助理解您正在尝试做什么或为什么自动加载无法工作。只需要基本的方法定义。我只是尝试使用Ruby的开放类在两个不同的类体中定义用户(没有混入!)。因此自动加载不起作用,因为app/models/user.rb
没有引用app/lib/integrations/ext/user.rb
我发布了第二个答案,提供了一种我认为您尝试执行的操作的替代方法。我的问题是试图避免使用混合,而只是使用多个类定义。可能误读了您的答案问题。避免混入成功了吗?谢谢你的这种替代方法。您确实是对的,我想分离特定模型特有的代码(模型之间不共享)。您的方法让我想起了使用服务层来封装模型逻辑。我投了赞成票,但不打算将其作为答案。我想做的是在rails之外使用一种常见的Ruby习惯用法。我期待着看到被接受的解决方案是什么样子。祝你好运
MyNamespace::UserRepo::create_admin!(params[:user])