Second one. Most methods take symbols as their arguments. Here is why: When to use symbols instead of strings in Ruby?
This is the method signature of before_action
:
before_action(names, options)
As you can see, it takes first a name
and then some options as its argument. By convention, options
is a hash. Because Ruby allows you to drop a lot of "line noise", the brackets around the hash are implicit. You could write the same line as:
before_action(:find_course, { only: [:show, :edit, :update, :destroy] })
So :find_course
is not the key for the hash, but only
is.
Furthermore, :find_course
is not the name of a model but the name of a method. By passing the method name (as a symbol) to before_action
, the method will be executed before each request is processed (i.e. before #show
for example). Through the options
, it is possible to limit the action to certain operations. These are again provided as symbols, since they are internal identifiers. Technically, they all reference methods on the controller again.
Passing symbols that reference methods or classes is a very common practice in Rails. belongs_to
uses the same convention to add association methods to your models (belongs_to :user
). Rails will attempt to connect this method name to a model called User
unless you specify otherwise. This is part of the magic of Rails that makes it very easy to use, but a bit hard to understand in the beginning.
Having a good understanding of Ruby and symbols vs. strings helps you make more sense of this.
Edit:
To understand what "internal identifier" means, check out the question linked to by Deep in a comment to your question: Why do callbacks use symbols in Ruby on Rails It explains why you need to reference a method, instead of doing something like this:
before_action(find_course)
In summary, this would execute find_course
and pass its result to before_action
, which is not what you want. So you need to reference the method somehow so that it can be called later.
In other languages, this could be done with strings or by passing in a function object. For example, in Python you could do something before_action(print)
. This would pass a reference to the function without calling it. Sadly, this is not possible in Ruby, so we need to pass in a string or symbol with the name of the method, which brings us back to the first linked question about the benefits of symbols over strings as references.