1

I'm new to Ruby and Ruby on Rails, coming from a background of C-like languages.
Here is some code that I found in the application_controller.rb file:

def current_user
    @current_user ||= Renter.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user

def authorize_user
    redirect_to '/login' unless current_user
end

Here is what I don't understand about it:
- On line 4, is :current_user invoking the current_user instance method, or directly accessing the @current_user instance variable?
- On line 7, is current_user invoking the current_user instance method, or directly accessing the @current_user instance variable?
- On line 2, is :user_id a variable or is it more like a string literal being used as a key? Kind of like in JavaScript one might write session["user_id"] to get theuser_id property of the session object.

2 Answers 2

2

class methods aren't relevant in this example - they aren't being used here.

Instance variables will never call methods when they are get/set.

Although the opposite does sometimes happen. It's a very common pattern to create getter/setter methods for instance variables, so common that attr reader/writer/accessor helpers are defined in ruby core. If you write attr_accessor :foo, then foo= and foo will get/set the instance variable.

But this does not happen by default.

To answer your other question:

A symbol :user_id starts with a colon and is similar to a string. The difference between a symbol and a string may seem arbitrary, but it is an important concept in Ruby and making the distinction in your head is a good idea.


To respond to your comment:

Line 4, helper_method :current_user is really something specific to rails, consider it "rails magic" if you like. In effect this is making your current_user method callable from views (whereas by default it would only be available in the controller). :current_user is a symbol which is used to reference the current_user method. Not necessarily something you have to understand in total detail, it would suffice to know that helper_method takes a symbol with the same name as a method and makes that method available to views. As far as I'm aware, it's only relevant to Rails controllers.

It's somewhat common in Ruby to use symbols that refer to method names. It's a more intermediate concept. You can see another example in send:

def asd
  return 0
end

class Foo
  def instance_method_bar
    return 0
  end
  def self.class_method_bar
    return 0
  end
end

# how the methods are typically called
asd
Foo.new.instance_method_bar
Foo.class_method_bar

# another way to call them, using send
send(:asd)
Foo.new.send(:instance_method_bar)
Foo.send(:class_method_bar)

I'm not recommending you use send unless you need to, but hopefully it will make it more clear how the symbol :current_user is being used in helper_method

Line 7 is the current_user method being called.

Sign up to request clarification or add additional context in comments.

5 Comments

What are :current_user on line 4 and current_user on line 7 referencing? Also is :current_user a symbol?
I recommend you go through a fairly in-depth ruby textbook (no need to do the examples, just understand the concepts). Not saying you couldn't learn Rails without doing this but having a solid Ruby understanding really comes in handy when debugging Rails or deconstructing the "magic".
Thanks a bunch. That one part about :current_user still being a symbol really clears up come confusion. For a moment I was thinking that perhaps that colon operator causes functions to be called in some contexts while it denotes a symbol in other contexts. But now I know it's a rails magic thing. Kind of like in PHP when I pass a string as a parameter which contains the name of a function that will be called.
I find it interesting that you state: "class methods aren't relevant in this example - they aren't being used here." If that's the case, then what is @current_user?
1

Let's tackle your questions one at a time.

  • On line 4, :current_user is a method, most likely used to return the current_user, so you can access username, or email, or whatever value the user has.

  • On line 7, it is still the same method. In this case, Ruby is checking whether a current_user object exists. You can think of unless as if not. So the code will redirect to login if current_user is false, which will happen if current_user == nil. If the user is logged in, current_user != nil, and the redirect does not happen.

  • On line 2, :user_id is a symbol, and session is a hash, which is key-value pair, such as { a: 1, b: 2 }, and you access the value with the key using the [] method, so session[:user_id] is returning the value of the user_id. In Ruby, you can use anything as the key, symbols are used because they are always unique, the object id of :two and :two is the same, whereas the id is different for "two" and "two".

2 Comments

1. Why do the method calls on lines 4 and 7 look different (one has a colon before it and the other does not)? 2. Is :current_user the declaration of a symbol? 3. Is a symbol a primitive like a string, or does it hold a value, like a variable?
you can think of :current_user as an argument, it is telling helper_method which methods to call, so it's more of an identifier. The current_user without colon is actually calling the method itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.