Rails - How to set global instance variables in initializers?

12,090

Solution 1

In your initilizers/predictor.rb you shall define your recommender not as:

recommender = CourseRecommender.new

but as:

::Recommender = CourseRecommender.new

this way you define a constant throughout the scope of your application, instead of defining a local variable. In your initializer and controller you access it as Recommender.

Solution 2

I solve the problem. But instead of setting a global instance, I use the Singleton pattern.

Here's the code:

# 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

Solution 3

I am not familiar with that gem, but it seems like you should have your code in ApplicationController.

in 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")

and then in your controler:

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

Related videos on Youtube

Trantor Liu
Author by

Trantor Liu

I'm the CEO and founder of CakeResume - https://www.cakeresume.com.

Updated on September 14, 2022

Comments

  • Trantor Liu
    Trantor Liu over 1 year

    I was using the predictor gem. I initialized the recommender in 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")
    

    And then I wanted to use the recommender in the CourseController like this:

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

    How could I set recommender as an application controller variable so I could access it in the controllers?

  • zetetic
    zetetic almost 10 years
    Just to clarify, the code should go in the controller, and not in the initializer. You might also consider making it a filter if it is only required for certain requests.
  • Trantor Liu
    Trantor Liu almost 10 years
    Right. But I think it makes more sense to put the code in an initializer. Thanks anyway.
  • xiy
    xiy almost 8 years
    This is a much cleaner and more maintainable pattern than the accepted answer, especially for testing.
  • iconoclast
    iconoclast about 5 years
    I agree with @xiy, but this highlights a problem with Stack Exchange sites. They fail to distinguish between the question and the problem. This answer solves the problem behind the question, but the accepted answer actually answers the question (because the question assumed a particular sort of solution when it was asked). This exposes a simplistic data model used by Stack Exchange sites.
  • Todd
    Todd almost 4 years
    Is :: needed if we're in an initializer? Would this already be within the global namespace?