Skip to content
Alain Becam edited this page Feb 9, 2023 · 5 revisions

You know Rails

Seek is mostly vanilla Rails, but add functionalities through its library (most often using concerns, like is_an_asset, and action_controller filters, such as before_action) and several Gems.

You don’t know Rails and you don’t know Ruby

On most aspect Ruby is an easy language to learn, and it is easy to find tutorials from the official page: Why Ruby (but some are obsolete!)

We compile some main particularities (compared to other languages) below, with links to relevant documentation.

We recommend first Ruby in Twenty Minutes

Then (at least) the free part “Learn Enough Ruby to Be Dangerous”:

Mostly:

  • Concatenation and interpolation , "#{first_name} is my first name." and the difference between “ and ‘

    Also shown on this page, Ruby uses snake case as naming convention, so a method will be method_name \

  • Array iteration how to iterate the Ruby way.

Then you need to know about symbols, you find a nice explanation here: FAQ page 6

Class variable and class instance variables, also in the faq: FAQ page 8 and mixin on the same page (it’s probably a good idea to read the full FAQ).

  • A very important information from this page:

Can a class definition be repeated?

A class can be defined repeatedly. Each definition is added to the last definition. If a method is redefined, the former one is overridden and lost.

Which means that Ruby will not raise an error if you write twice the same method, but will use the last one!

  • Different ways to call a method in Ruby:
# keyword argument
def hello(name: "Anonymous")
    puts "Hello #{name}"
end

# position argument
def hello3(name = "Anonymous")
    puts "Hello #{name}"
end

# position argument with and without default value
def hello4(before_name, name = "Anonymous", first_name= "Bob", after_name)
    puts "Hello #{before_name} #{first_name} #{name} #{after_name}"
end

hello name: "Paul" # Hello Paul
hello # Hello Anonymous, uses the default value
hello()
hello(name:"Paul") # Hello Paul
hello(name: :Paul) # Hello Paul (Use the symbol Paul)
hello(name: "Larry") # Hello Larry (specify which parameter)
hello(:name => "Bob") # Hello Bob
#hello("Larry") -> return an exception
hello3(name= "Larry") # Hello Larry
hello3( "Larry") # Hello Larry
hello3 # Hello Anonymous
hello4("Dr","Senior") # Hello Dr Bob Anonymous Senior
hello4("Dr","Larry", "Senior") # Hello Dr Bob Larry Senior
hello4("Dr","Larry", "Paul", "Senior") # Hello Dr Paul Larry Senior
  • A method that return a boolean is finished by ?:
def is_it_true?(x)
    if [true, false].include? x
        x == true
    else
        false
    end
end

puts is_it_true?(false)
puts is_it_true?(true)
puts is_it_true?("banana")

The line [true, false].include? x checks that true or false or included in x, thus it can be considered as a boolean.

Generally, when a condition should be false for the contained code-block to execute, we use unless instead of if !:

unless do_not_show?(that)

do_something

end

And conditions/actions can be written in one line when there is no need for a block:

do_something unless do_not_show?(that)

do_something if do_show?(that)

  • A method finished by ! is a bang method, the exclamation mark shows that it is dangerous:

    • It is a convention for methods that change the value of the parameter, so name.downcase create a new variable, but name.downcase! will modify name directly.
    • Mostly with rails, it indicates that a method will raise an exception if it fails, instead of returning false:

@post.update(post_params) will return false if it fails

@post.update!(post_params) will raise an exception if it fails

It is also used in tests, for instance when saving: model.save!

  • A very good description of objects, classes and methods in Ruby: Objects

  • All variables scopes: Ruby Variable Scope

  • Modules: Modules

  • Arrays and hashes (next page): Arrays

  • Classes in Ruby can be changed at runtime, it’s monkey patching. It can be handy but dangerous: Scope the monkey

The wikidoc Ruby book is relatively up to date and complete: Ruby Programming

Rails

Rails is a complete solution for writing Web Applications. It has an official documentation that is really well done and available for all versions. It is strongly recommended that you spend the time to read it: Ruby On Rails guide

It is probably a good idea to build the example application from the “Getting Started with Rails” introduction chapter.

One important aspect of Rails is that it will assume many things for you, such as helper methods for all possible routes and corresponding controller action, for instance: select_person_path for the model people (Rails also automatically maps person to people) for the method select of person. It can save a considerable amount of time, but can sometimes be frustrating. You can see all routes helpers for your application by adding /rails/info/routes to the url of your application. So if your application run on http://127.0.0.1:3000 (default localhost Rails server), it will be on http://127.0.0.1:3000/rails/info/routes Another thing is that what you see (as an user) is mostly what you get: any /path/ correspond to a set of views (a folder)/model/controller. Subpaths correspond to a ERB template file in the /path/ view folder. Views are often composed of sub-elements, that can be shared, called partials, called using render: <%= render "menu" %>.

  • When looking at the Seek code base, you might also think that some variables are magically coming or that methods seems to be missing. It is because Seek uses concerns (act_as_) and filters:

In model:

acts_as_asset

It is a concern that will makes this models act as an asset

In controllers:

before_action :find_and_authorize_requested_item,:only=>[:edit, :manage, :update, :manage_update, :destroy, :show,:new_object_based_on_existing_one]

Is a filter that will find and authorize a requested item only for the given controller method (edit, manage, …), which is why you might think a method is missing its parameter, the filter provide it for the method, and in that case, only if authorized. If not authorized, the item will not be provided.