Ruby & Rails — some thirst satisfiers!

This blog covers:

  • Symbols
  • Instance and Class variables
  • ERB
  • use of as: in rails route
  • Render Vs Redirect in Rails
  • Resources CRUD — using :only
  • Instance Variable vs Local Variable
  • Sending a message by redirect_to
  • Partials
  • Rbenv
  • Gem
  • Bundler

Symbols

Symbols are the pills which we generally swallow without knowing what exactly are they! So what exactly are these things and why to use them?

:yes
employee = {:name => "Abhinav", :age => 22}
class Employee
attr_accessor :name
end

Symbols are just like string but Immutable and they refer to the same object always.

"yes" + " Abhinav"       # "yes Abhinav"
:yes + "some string" # Error. Symbols are immutable!

They also save a lot of memory as they always refer to same object.

"name".object_id    #70230235721980
"name".object_id #70230235705660
:name.object_id #86108
:name.object_id #86108

Thus using symbols in hash is much better than using strings.

# not so efficient - Case 1
# ----------------
employeeDetails = {"name" : "Abhinav", "age" : 22}
# ----------------
# Efficient - Case 2
# -----------------
employeeDetails = {:name => "Abhinav", :age => 22}
# -----------------

We don’t have to carry the overhead of mutability as in case 1 — name and age don’t have to be mutable. Thus for 100 such hashes, name and age would make 100 instances which is not good. While in case 2, :name and :age have a single instance.

Another hash syntax which looks like JSON. Note that name is a symbol here without the prefixed colons.

person = {name: "Abhinav"}

We can also use symbols as named parameters to a function.

Person.age(:dob => "1996")

We can use symbols in method calls. This is one important use case. See the examples below.

class Greeting
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Greeting.new
k.send :hello, "gentle", "readers" # "Hello gentle readers"
#----------------------------------------------------------
class Dog  
attr_accessor :name
end

dog1 = Dog.new
dog1.name = "Einstein"

Thats why we use symbol after attr_accessor and thats how it internally sets up the getter and setter.

What is @ and @@ in class?

@ is an instance variable in class which is specific to an object of the class.

@@ is class variable, also called static variable and its initialized on creation and is shared by all objects of the class.

class Test
@@shared = 1

def value
@@shared
end

def value=(value)
@@shared = value
end
end

class AnotherTest < Test; end

t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2

x = Test.new
puts "x.value is #{x.value}" # 2

a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3

What is <% %> or <%= %> in rails?

This is used in Embedded Ruby (ERB) template. Within an ERB template, Ruby code can be included using both <% %> and <%= %> tags. The <% %>tags are used to execute Ruby code that does not return anything, such as conditions, loops or blocks, and the <%= %> tags are used when you want output.

What is as: in routes.rb file in rails?

get 'signup', to: 'users#signup', as: 'signup1'

In routes.rb file, what is the use of as:?

For accessing the signup view we can use -

<%= link_to "Sign Up", signup1_path %>

This signup1_path works because we use signup1 as as:. Without this as: , it won’t work

Render Vs Redirect

Redirect is used to tell the browser to issue a new request. Whereas, render only works in case the controller is being set up properly with the variables that needs to be rendered. Render creates the response to be sent back to the browser. It doesn’t affect the url in the browser.

render :signup   #or render "signup"
redirect_to signup_path

Resource CRUD — using :only and :except

By default, Rails creates routes for the seven default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application by using resource. You can use the :only and :except options to fine-tune this behavior. The :only option tells Rails to create only the specified routes.

resources :mobiles, :only => [:index, :show]

Instance variables vs local variables

A local variable that is defined inside one method, for example, cannot be accessed by another method. In order to get around this limitation, we can use instance variables inside Ruby classes. Instance variables are the variables starting with @ sign.

In Controllers class in rails, all the instance variables are passed to views class and can be accessed in html.erb files by <%= @variable %> syntax.

How to send a message from redirect_to to the redirected page?

One can think of passing arguments through redirect and then catching them through params[:]. Thats what my initial thought was!

redirect_to controller: 'user', action: 'edit', id: 3, something: 'parameter'
# would yield
/user/3/edit?something=parameter

But this shows the GET params in the bar.

A way out tool — flash. Used for passing the messages.

flash[:notice] = "Post successfully created"
# --------------------------------------------
# in show.html.erb
<% if flash[:notice] %>
<div class="notice"><%= flash[:notice] %></div>
<% end %>

What is Partials?

Partial templates — usually just called “partials” — are another device for breaking the rendering process into more manageable chunks. With a partial, we can move the code for rendering a particular piece of a response to its own file.

The file name should begin with an underscore sign.

# Filename is _navbar.html.erb in layouts directory in views.
<%= render 'layouts/navbar' %>

What is rbenv?

Rbenv stands for Ruby Environment. We don’t have to use the system ruby everytime for the project. We can have different local versions of ruby to run different projects. More information here.

What is gem? And where is it stored?

Most of the time, gems just work. We require them and they do the work. A good read on how the gems work is this.

Node modules are downloaded in node_modules directory by package.json.

You can get where the gems are installed by this command.

$ gem environment
Output: /Users/<username>/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems

This link tells how the gems are required in the project by overriding the default ruby require.

What is Bundler in rails?

Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed. Bundler is an exit from dependency hell, and ensures that the gems you need are present in development, staging, and production.

Earlier there were setup scripts to install the right version of gems for your project. But then the rails version started developing fast and there were gems which were not compatible with the new versions and the new gem versions were not compatible with old rails. And then there were multiple rails app.

One solution was to use rbenv or rvm. But they use to take a bit time to setup. With Bundler, we rarely have to think about our dependencies. Our apps usually just work. And Bundler takes a lot less setup than rvm gemsets did.

So, Bundler does two important things -

  • It installs all the gems we need
  • and it locks RubyGems down, so those gems are the only ones we can require inside that Rails app. Thats why Gemfile.lock is made after every bundle install.

A more detailed read can be found here.

You may contact the author at me@abhinavrai.com