Using structs in Ruby on Rails gives dynamic constant assignment (SyntaxError)

12,117

Solution 1

The error explains what the problem is - you have a constant being assigned in a context that's too dynamic - i.e. inside the index method.

The solution is to define it outside:

DashItem = Struct.new(:name, :amount, :moderated)
def index
  @dashboard_items = []
  ...

Solution 2

If you want to keep the whole thing neatly inside your index method you could do this:

def index
  @dashboard_items = []
  # Set the name of your struct class as the first argument
  Struct.new('DashItem', :name, :amount, :moderated)
  ...
  # Then when you want to create an instance of your structure
  # you can access your class within the Struct class
  @dashboard_items << Struct::DashItem.new(c.to_s, obj.count, obj.moderated)
end

As gunn said, you just can't explicitly assign a constant within a method like that...

This solution is explained more in the ruby docs here, second example on the page.

Solution 3

Another simple option here would be to use a local var instead of a constant when assigning and instantiating the Struct in a dynamic setting:

def index
  # ...
  dash_item = Struct.new(:name, :amount, :moderated)  

  # ...
    @dashboard_items << dash_item.new( ... )
  # ...
end    
Share:
12,117
berkes
Author by

berkes

Bèr Kessels is entrepeneur and owner of webdevelopment company berk.es. Open Source Webdelopment. Specialised in Ruby, Rails and Sinatra.

Updated on June 24, 2022

Comments

  • berkes
    berkes about 2 years

    In my controller I have the following simplified code:

    def index
      @dashboard_items = []
      DashItem = Struct.new(:name, :amount, :moderated)  # Error is here
    
      [:page, :post].each do |c|
        obj = c.to_s.capitalize.constantize
        @dashboard_items << DashItem.new(c.to_s, obj.count, obj.count_moderated)
      end
    end
    

    But Ruby gives the following error:

    dynamic constant assignment (SyntaxError)

    on the line marked above.

    Which, AFAIK, means that the constant DashItem is already defined. Is this correct? And what to do about it?