如果全局命名空间中存在相同名称,则在范围控制器中Rails错误的模型命名空间查

时间:2014-04-10 12:04:43

标签: ruby-on-rails ruby ruby-on-rails-4

我有一个像这样声明的问题模型:

Question < ActiveRecord::Base

应用程序/模型/ question.rb

和一个Quiz :: Question-model声明如下:

Quiz::Question < ActiveRecord::Base

应用程序/模型/测验/ question.rb

另外,我在app / models / quiz.rb中有一个测验模型。

现在的问题是,如果我从某些作用域控制器的视图中调用::Quiz::Question.inspect(或.table_name或.name或其他所有内容),它会在全局命名空间中返回有关我的问题模型的信息,而不是测验命名空间中的问题模型。这意味着ruby仍然指向全局命名空间中的Question-class,而不是使用我在Quiz :: - 命名空间中指定的那个。

如何在不重命名全局命名空间问题模型的情况下调用我的Quiz :: Question-class?

验证实验

如果我将这两个方法添加到这两个类中:

class Question
  def self.test
    'Hello from global Question'
  end
end

class Quiz::Question
  def self.test
    'Hello form namespace Quiz'
  end
end

然后只需调用::Quiz::Question.test(或Quiz::Question.test)它会在某些作用域控制器和视图(带scope :module => "..."的路径)中显示“Hello from global Question”。如果我从我的全局命名空间(如application.html.erb)中的视图或控制器调用:: Quiz :: Question,它会显示预期结果( - &gt; quiz-namespace中的问题模型)。

6 个答案:

答案 0 :(得分:3)

不确切知道问题是什么(也许它与rails自动加载有关),但我通过添加&#34; require&#34;来解决它。我的测验模型中的陈述:

class Quiz < ActiveRecord::Base
  require 'quiz/question'
end
app / models / quiz.rb

中的

答案 1 :(得分:1)

对于那些寻找与类相关的答案而不是表的人来说,似乎ruby不区分不同名称空间中的两个同名的类,所以你应该总是以不同的方式命名类本身。

以下是一个解释: https://makandracards.com/makandra/20633-ruby-constant-lookup-the-good-the-bad-and-the-ugly

答案 2 :(得分:0)

您可以在模型中明确设置表名,但是您不应该调用Quiz::Question.table_name而不是::Quiz::Question.table_name吗?或者这是一个错字?

class Quiz::Question < ActiveRecord::Base
  self.table_name = 'quiz_questions'
end

答案 3 :(得分:0)

它正在访问您要访问的常量,只有table_name返回两个类的某些值。此外,ActiveRecord :: Base的inspect方法被定义为显示数据库表的内容,并且由于两个类都指向同一个表,因此两个clase的结果都是identitcal。您可以通过以下方式检查它是否正在调用正确的类:

::Quiz::Question.name

实验

尝试对两个类进行define方法测试:

class Question
  def self.test
    'Hello from global Question'
  end
end

class Quiz::Question
  def self.test
    'Hello form namespace Quiz'
  end
end

然后做:

::Quiz::Question.test

看看你会得到什么结果

答案 4 :(得分:0)

您应该在table_name_prefix模块中设置Quiz

# app/models/quiz.rb
module Quiz
  def self.table_name_prefix
    'quiz_'
  end
end

# app/models/quiz/question.rb
class Quiz::Question < ActiveRecord::Base
end

# app/models/question.rb
class Question < ActiveRecord::Base
end

然后:

Question.table_name
#=> "questions"

Quiz::Question.table_name
#=> "quiz_questions"

答案 5 :(得分:0)

实际上,对于你的两个测验::问题&amp;问题模型,即使你的模型不同,Rails会认为它们具有相同的表名,除非你指定它:

class Quiz::Question < ActiveRecord::Base

  def self.table_name_prefix
  'quiz_'
  end

  [...]

end