Home > Blockchain >  What is the difference between :id, id: and id in ruby?
What is the difference between :id, id: and id in ruby?

Time:08-06

I am trying to build a ruby on rails and graphQL app, and am working on a user update mutation. I have spent a long time trying to figure it out, and when I accidentally made a typo, it suddenly worked.

The below is the working migration:

module Mutations
  class UpdateUser < BaseMutation
    argument :id, Int
    argument :first_name, String
    argument :last_name, String
    argument :username, String
    argument :email, String
    argument :password, String

    field :user, Types::User
    field :errors, [String], null: false

    def resolve(id:, first_name:, last_name:, username:, email:, password:)
      user = User.find(id)
      user.update(first_name:, last_name:, username:, email:, password:)
      { user:, errors: [] }
    rescue StandardError => e
      { user: nil, errors: [e.message] }
    end
  end
end

The thing I am confused about is when I define the arguments, they are colon first: eg :id or :first_name

When I pass them to the resolve method they only work if they have the colon after: eg id: or first_name:

When I pass the variables to the update method, they use the same syntax of colon after, for all variables other than ID. For some reason, when I used id: it was resolving to a string "id", and using colon first :id was returning an undefined error.

It is only when I accidentally deleted the colon, and tried id that it actually resolved to the passed through value.

My question for this, is why and how this is behaving this way? I have tried finding the answer in the docs, and reading other posts, but have been unable to find an answer.

Please someone help my brain get around this, coming from a PHP background, ruby is melting my brain.

CodePudding user response:

It's going to take some time to get used to Ruby, coming from PHP, but it won't be too bad.

Essentially id is a variable, or object/model attribute when used like model_instance.id. In PHP this would be like $id or $object_instance->id.

When you see id: it is the key in a key-value pair, so it expects something (a value) after it (or assumes nil if nothing follows, often in method definitions using keyword arguments like your example). A typical use might be model_instance.update(id: 25) where you are essentially passing in a hash to the update method with id as the key and 25 as the value. The older way to write this in Ruby is with a "hash rocket" like so: model_instance.update(:id => 25).
More reading on Ruby hashes: https://www.rubyguides.com/2020/05/ruby-hash-methods
More reading on keyword arguments: https://www.rubyguides.com/2018/06/rubys-method-arguments

Now if you're paying attention that hash rocket now uses the 3rd type you're asking about. When you see a colon preceding a string like that it is called a "symbol" and it will take some time to get used to them but they are essentially strings in Ruby that are one character fewer to define. (I mean there is more to it than that, but you will learn that as you go.) Instead of using 'id' or "id" as a string, Ruby folks like to use :id as a symbol and it will typically auto-convert to a string when needed. A good example might be an enumerator of sorts.

state = :ready
if sate == :ready
  state = :finished
else
  state = :undefined
end

More reading on Ruby symbols: https://www.rubyguides.com/2018/02/ruby-symbols

  • Related