How to access class variable in Model class

10.6k views Asked by At

I want to define the class variable test, threshold

so that I can use Order.test, Order.threshold in my Rails app

but I can not access the class variable when using the rails console

I must misunderstand something, where's the problem? Thanks.

class Order < ActiveRecord::Base
  @@test=123
  @@threshold = {
    VIP: 500,
    PLATINUM: 20000
  }

Here is the rails console

irb(main):001:0> Order.class_variables
=> [:@@test, :@@threshold]
irb(main):002:0> Order.test
NoMethodError: private method `test' called for #<Class:0x007fe5a63ac738>
2

There are 2 answers

1
apneadiving On BEST ANSWER

Do this:

class Order < ActiveRecord::Base
   cattr_reader :test, :threshold
   self.test = 123
   self.threshold = {
     VIP: 500,
     PLATINUM: 20000
   }
end  

Order.test

Or I'd use constants:

class Order < ActiveRecord::Base
   TEST = 123
end

Order::TEST
0
Michael Stalker On

I would just use class methods:

class Order < ActiveRecord::Base
  def self.test
    123
  end

  def self.threshold
    { VIP: 500, PLATINUM: 20000 }
  end
end

Constants would work, as well, but if you already have code that expects Order.test and Order.threshold to exist, you'd have to change your code to call the constant instead. Plus, Avdi Grimm gives some good reasons for using methods instead of constants in a blog post.

The reason accessing class variables won't work the way you expected is that Ruby restricts access to variables like this. You need to either define accessor methods directly (like self.test or self.threshold), or indirectly using something like cattr_reader. You could also use cattr_accessor if you need to write to the variables from the outside world.

I would generally recommend avoiding class variables, though. They have some unintuitive behavior.