【问题标题】:Rails - How to set global instance variables in initializers?Rails - 如何在初始化程序中设置全局实例变量?
【发布时间】:2014-06-28 14:44:05
【问题描述】:

我使用的是predictor gem。我在initializers/predictor.rb中初始化了推荐器:

require 'course_recommender'    

recommender = CourseRecommender.new

# Add records to the recommender.
recommender.add_to_matrix!(:topics, "topic-1", "course-1")
recommender.add_to_matrix!(:topics, "topic-2", "course-1")
recommender.add_to_matrix!(:topics, "topic-1", "course-2")

然后我想像这样在 CourseController 中使用推荐器:

class CourseController < ApplicationController
  def show
    # I would like to access the recommender here.
    similiar_courses = recommender.similarities_for("course-1")
  end
end

如何将recommender 设置为应用程序控制器变量,以便在控制器中访问它?

【问题讨论】:

    标签: ruby-on-rails controller initializer


    【解决方案1】:

    在您的initilizers/predictor.rb 中,您应将您的推荐人定义为:

    recommender = CourseRecommender.new
    

    但作为:

    ::Recommender = CourseRecommender.new

    通过这种方式,您可以在整个应用程序范围内定义一个常量,而不是定义一个局部变量。在您的初始化程序和控制器中,您可以通过 Recommender 访问它。

    【讨论】:

    • 如果我们在初始化器中,是否需要::?这是否已经在全局命名空间中?
    【解决方案2】:

    我解决了这个问题。但我没有设置全局实例,而是使用Singleton 模式。

    代码如下:

    # lib/course_recommender.rb
    require 'singleton'
    class CourseRecommender
      include Predictor::Base
      include Singleton
      # ...
    end
    
    # initializers/predictor.rb
    @recommender = CourseRecommender.instance
    
    # Add records to the recommender.
    @recommender.add_to_matrix!(:topics, "topic-1", "course-1")
    @recommender.add_to_matrix!(:topics, "topic-2", "course-1")
    @recommender.add_to_matrix!(:topics, "topic-1", "course-2")
    
    # controllers/course_controller.rb
    require 'course_recommender'
    class CourseController < ApplicationController
      def show
        similiar_courses = CourseRecommender.instance.similarities_for("course-1")
      end
    end
    

    【讨论】:

    • 这是一种比公认的答案更简洁、更易于维护的模式,尤其是对于测试而言。
    • 我同意@xiy,但这凸显了 Stack Exchange 网站的一个问题。他们无法区分 questionproblem。这个答案解决了问题背后的问题,但接受的答案实际上回答了问题(因为问题在被问到时假定了特定类型的解决方案)。这暴露了 Stack Exchange 站点使用的简单数据模型。
    【解决方案3】:

    我不熟悉那个 gem,但您似乎应该将代码放在 ApplicationController 中。

    在应用控制器中:

    @recommender = CourseRecommender.new
    
    # Add records to the recommender.
    @recommender.add_to_matrix!(:topics, "topic-1", "course-1")
    @recommender.add_to_matrix!(:topics, "topic-2", "course-1")
    @recommender.add_to_matrix!(:topics, "topic-1", "course-2")
    

    然后在你的控制器中:

    class CourseController < ApplicationController
      def show
        # I would like to access the recommender here.
        similiar_courses = @recommender.similarities_for("course-1")
      end
    end
    

    【讨论】:

    • 澄清一下,代码应该放在控制器中,而 not 放在初始化器中。如果仅某些请求需要它,您也可以考虑将其设置为过滤器。
    • 对。但我认为将代码放在初始化程序中更有意义。还是谢谢。
    猜你喜欢
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多