2

I'm learning Ruby on Rails by example. I see in migration folder here is one sample code:

class RemoveOrderListNumberAndStateFromOrderLists < ActiveRecord::Migration[5.0]
  def up
    remove_column :order_lists, :order_list_number
    remove_column :order_lists, :state
  end

  def down
    add_column :order_lists, :order_list_number, :string
    add_column :order_lists, :state, :integer
  end
end

The thing I don't know is at this line:

class RemoveOrderListNumberAndStateFromOrderLists < ActiveRecord::Migration[5.0]

I know this command means: create a class, that is a subclass of ActiveRecord::Migration and also 5.0 is rails version of project. Thing that I don't know is: which ruby grammar name that allow you declare [number] after class in above case. I think the only way is an array, but not likely true in this case.

thanks

Trần Kim Dự
  • 5,872
  • 12
  • 55
  • 107

2 Answers2

4

The Ruby language comes with a lot of what is called "syntactic sugar," which allows you to express the same ideas in different ways. The purpose of sugar is to allow the programmer to find a way to express the idea in a way that makes the most sense to that individual.

In your case, the square brackets are just another way to call a method with arguments -- there's no functional difference. proc[] is another way to say proc.call(), so the brackets are just hiding the call. Usually, you only see these brackets in conjunction with lambdas. There's no specific "grammar name" that goes with this type of notation -- it's just notation.

Specifically, this is a class method being called on ActiveRecord::Migration that tells the class what migration version is being used. Note: if you have the release version of Rails, you shouldn't need that notation -- it should have been removed after the beta finished.

You can see where and how ActiveRecord::Migration uses that class method in the GitHub repository

    def self.[](version)
      version = version.to_s
      name = "V#{version.tr('.', '_')}"
      unless Compatibility.const_defined?(name)
        versions = Compatibility.constants.grep(/\AV[0-9_]+\z/).map { |s| s.to_s.delete('V').tr('_', '.').inspect }
        raise "Unknown migration version #{version.inspect}; expected one of #{versions.sort.join(', ')}"
      end
      Compatibility.const_get(name)
    end
MarsAtomic
  • 10,436
  • 5
  • 35
  • 56
1

If you check the source code, you'd see that this is used to find the Compatibility version of ActiveRecord::Migration, in your case, this would have returned the class ActiveRecord::Migration::Current so your migration would be a subclass of that class.

Currently, I think there are only 2 versions available: v4.2 and v5.0.

oreoluwa
  • 5,553
  • 2
  • 20
  • 27