Rails:在具有相同名称的模块上引用ActiveRecord模型

时间:2018-09-15 09:57:26

标签: ruby-on-rails

我定义了以下标准Rails ActiveRecord Foo

# app/models/foo.rb
class Foo < ApplicationRecord
end

我正在尝试从包含也名为Foo.find(..)的模块的层次结构中调用Foo

# lib/commands/bar.rb
module Commands
  module Bar
    module Create
      class Command
        def initialize(params)
          ...
          Foo.find(params[:foo_id]
          ...
        end
      end
    end
  end
end

# lib/commands/foo.rb
module Commands
  module Foo
    module Create
      class Command
        ...
      end
    end
  end
end

Ruby / Rails正在找到Commands::Foo而不是我的Foo模型并抛出undefined method 'find' for Commands::Foo:Module。。我如何指出正确的ActiveModel实现?

显而易见的答案是将Commands::Foo..重命名为Commands::Foos..,但我很好奇是否还有另一种方法:o)

2 个答案:

答案 0 :(得分:1)

如果要避免冲突,则应重命名模块。现有的结构笨拙,并且将对所有未来的维护者提出类似的问题。

我在您的代码中找到的最佳解决方案是确保您通过其完整路径调用适当的模块和方法:

2.3.3 :007 > ::Commands::Foo::Create::Command.new
"Commands::Foo::Command reached"
 => #<Commands::Foo::Create::Command:0x007ffa1b05e2f0>
2.3.3 :008 > ::Commands::Bar::Create::Command.new
"Commands::Bar::Command reached"
 => #<Commands::Bar::Create::Command:0x007ffa1b04f110>

您不应尝试覆盖或修改内部Rails调用,因为那样的话,您已经修改了框架以适合代码,这会导致无法预料的副作用。

答案 1 :(得分:0)

您可以尝试在 ::Foo 中调用Commands::Foo,它应该适合您的 Foo 模型