What is attr_accessor in Rails?

2018-01-29 20:15:02 +0000

attr_accessor is used to define an attribute for object of Model which is not mapped with any column in database. This answers question - What is attr_accessor in Rails.

1. attr_accessor Methods

attr_accessor creates two methods i.e. getter method and setter method.

**getter method **- it is used to retrieve value of the attribute

setter method - it is used to set value to the attribute

When to use attr_accessor in Rails?

Whenever you want to show certain attribute for particular form but you do not want to store it’s value in the database then you use attr_accessor for that model as follows,

Suppose we have a Model called user in out database with following fields,

  • id
  • name
  • age
  • city
  • profession

And we define attr_accessor :type_of_user as follows,

Class User < ActiveRecord::Base
   attr_accessor :type_of_user
end

Now, whenever you create a object of the class User then you can assign a value to it’s attr_accessor.

new_user = User.new(:name => 'Albert', :age => 23, :city => 'Ports S.')

This will create new object of class User and assign given attribute values. You can assign value to attr_accessor variable as follows,

ew_user.type_of_user = 'middle-aged'

This assigns ‘middle-aged’ value to the attribute type_of_user attr_accessor.

getter and setter in Action For attribute type_of_user getter and setter methods are created as follows,

# getter
def type_of_user
  @type_of_user
end

# setter
def type_of_user=(val)
  @type_of_user = val
end

And these are used whenever we assign or retrieve values from the attr_accessor.

  1. Usage in Classes Whenever changing value of the attr_accessor variables, we need to use self.variable_name = to assign new value to the variable. Otherwise, it will consider it as a local variable resulting into incorrect values.

For example,

class SimpleService

  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def process
    if false # some condition met
      name = 'Akshay'
    end
    name
  end
end

Here, it the above service class we have defined name as the attr_accessor. We need to change it’s value based on some condition. And we return it’s value from process method.

When we execute this class as,

SimpleService.new('John Doe').process
=> nil

We can see that process method has returned nil.

Explaination

In the block,

def process
  if false # some condition met
    name = 'Akshay'
  end
  name
end

As the if condition is false, and value of name is returned from the process method, name is considered as the local variable. Local variable name does not have any value. Thus, it returns nil.

Correction

To correct the above service class, we need to use explicity self when assigning value to the attr_accessor variable as given below,

class SimpleService

  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def process
    if false # some condition met
      self.name = 'Akshay'
    end
    name
  end
end

Now if we execute this class, we will get expected result as given below.

SimpleService.new('John Doe').process
=> "John Doe"
  1. Lifetime of attr_accessor attr_accessor is accessible throughout object’s lifecycle. When object is saved using any of ActiveRecord method, save, update etc. all attributes of Model other than attr_accessor are saved in the database.

How to Access Throughout lifecycle of object, you can access the value of attribute accessor as follows,

new_user.type_of_user
  1. Conclusion We learned what is attr_accessor in Rails and how to use it with Rails .

What's new in Ruby 2.5?

2017-10-12 09:27:58 +0000

Ruby 2.5.0-preview1 Released

useful image

We are pleased to announce the release of Ruby 2.5.0-preview1.

Ruby 2.5.0-preview1 is the first preview release toward Ruby 2.5.0. It introduces some new features and performance improvements, for example:

After installing the beta version through rvm …

 tinix   rvm install 2.5.0-preview1
Searching for binary rubies, this might take some time.
No binary rubies available for: debian/9/x86_64/ruby-2.5.0-preview1.
Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies.
Checking requirements for debian.
Requirements installation successful.
Installing Ruby from source to: /home/tinix/.rvm/rubies/ruby-2.5.0-preview1, this may take a while depending on your cpu(s)...
ruby-2.5.0-preview1 - #downloading ruby-2.5.0-preview1, this may take a while depending on your connection...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 13.4M  100 13.4M    0     0  1693k      0  0:00:08  0:00:08 --:--:-- 2192k
No checksum for downloaded archive, recording checksum in user configuration.
ruby-2.5.0-preview1 - #extracting ruby-2.5.0-preview1 to /home/tinix/.rvm/src/ruby-2.5.0-preview1....
ruby-2.5.0-preview1 - #configuring.............................................|
ruby-2.5.0-preview1 - #post-configuration..
ruby-2.5.0-preview1 - #compiling.........................................................................|
ruby-2.5.0-preview1 - #installing..............
ruby-2.5.0-preview1 - #making binaries executable..
Rubygems 2.6.14 already available in installed ruby, skipping installation, use --force to reinstall.
ruby-2.5.0-preview1 - #gemset created /home/tinix/.rvm/gems/ruby-2.5.0-preview1@global
ruby-2.5.0-preview1 - #importing gemset /home/tinix/.rvm/gemsets/global.gems.............................|
ruby-2.5.0-preview1 - #generating global wrappers........
ruby-2.5.0-preview1 - #gemset created /home/tinix/.rvm/gems/ruby-2.5.0-preview1
ruby-2.5.0-preview1 - #importing gemsetfile /home/tinix/.rvm/gemsets/default.gems evaluated to empty gem list
ruby-2.5.0-preview1 - #generating default wrappers........
ruby-2.5.0-preview1 - #adjusting #shebangs for (gem irb erb ri rdoc testrb rake).
Install of ruby-2.5.0-preview1 - #complete
Ruby was built without documentation, to build it run: rvm docs generate-ri
 tinix  
 

The 2.5.0-preview1Ruby language version has just been released. Because it is not a stable version, its use is not yet recommended .

** Inverse backtrace**

The backtrace (list of methods that were run before an error happened) will start to be displayed in reverse order. Using the following code as an example:

#file test.rb

def a
   b
end

def b
   c
end

def c
   raise 'error'
end

a

if the same file is run in ruby 2.4 you get…

$ ruby test.rb
test.rb:10:in `c': error (RuntimeError)
    from test.rb:6:in `b'
    from test.rb:2:in `a'
    from test.rb:13:in `<main>'
	Rescue / else / ensure will be allowed inside of / end blocks

Running with Ruby 2.4:

Currently we can only capture exceptions within methods or blocks begin/ end, ie:

begin
  raise 'boom'
rescue Exception => e
  puts "Error caught: #{e.message}"
end

: Output Error caught: boom

def my_method
  raise boom
  rescue Exception => and
  puts "Error caught: # {e.message}"
end

: Output Error caught: boom.

But the code below doesn’t work:

[1, 2, 3].map do |i|
  raise 'boom'
  rescue Exception => e
  puts "Error caught: #{e.message}"
end
syntax error, unexpected keyword_rescue, expecting keyword_end
rescue Exception => e

Running with Ruby 2.5:

In the version that is about to be released, this is possible. The output of the above code will be:

Captured error: boom
Captured error: boom
Captured error: boom

New method yield_self

According to the official documentation Ruby 2.5

  • Yields self to the block and returns the result of the block.

Although very similar to the tapclass method Object(which is very useful, by the way), your returns are different.

While with the method tapyou open a block and at the end the object itself is returned, with the yield_self, the result of the block is returned.

Example:

object.tap {| obj | obj.save} # => object

The save method was called, but object is returned

object.yield_self {| obj | obj.save} # => true
#The last block execution will be returned.
#That is, assuming that the `save` method returns` true`,
#the return of this entire line will be `true` too

I could not think of a practical case to use it, but certainly had a reason to have been added :)

Other changes

The new version will also bring other new features, such as support for Unicode version 10, which includes 56 emojis created this year . You can see a complete list with all the news in this document .

To install Ruby 2.5 (though not yet recommended for not being a stable release) through RVM, simply run:

rvm install 2.5.0-preview1

for more information visit Ruby 2.5.0-preview1 Released

Yes!!! Enjoy Ruby 2.5.0-preview1 Released

redirect_to(options = {}, response_status = {}) protected

2017-10-02 21:25:18 +0000

Redirects the browser to the target specified in options. This parameter can take one of three forms:

  • Hash - The URL will be generated by calling url_for with the options.
  • Record - The URL will be generated by calling url_for with the options, which will reference a named URL for that record.
  • String starting with protocol:// (like http://) - Is passed straight through as the target for redirection.
  • String not containing a protocol - The current protocol and host is prepended to the string.
  • :back - Back to the page that issued the request. Useful for forms that are triggered from multiple places. Short-hand for redirect_to(request.env["HTTP_REFERER"])

Examples:

 redirect_to :action => "show", :id => 5
  redirect_to post
  redirect_to "http://www.rubyonrails.org"
  redirect_to "/images/screenshot.jpg"
  redirect_to articles_url
  redirect_to :back

The redirection happens as a “302 Moved” header unless otherwise specified.

Examples:

redirect_to post_url(@post), :status => :found
  redirect_to :action=>'atom', :status => :moved_permanently
  redirect_to post_url(@post), :status => 301
  redirect_to :action=>'atom', :status => 302

It is also possible to assign a flash message as part of the redirection. There are two special accessors for commonly used the flash names alert and notice as well as a general purpose flash bucket.

Examples:

  redirect_to post_url(@post), :alert => "Watch it, mister!"
  redirect_to post_url(@post), :status=> :found, :notice => "Pay attention to the road"
  redirect_to post_url(@post), :status => 301, :flash => { :updated_post_id => @post.id }
  redirect_to { :action=>'atom' }, :alert => "Something serious happened"

When using redirect_to :back, if there is no referrer, RedirectBackError will be raised. You may specify some fallback behavior for this case by rescuing RedirectBackError.

Using Delayed Jobs in Rails

2017-09-26 09:00:40 +0000

When creating a web application sometimes need arises that we have to schedule some jobs during the execution of a particular method. Due to these job the render of the page has to wait until the task gets over. This waiting can be sometimes annoying because a user who is waiting for a job to get completed will have to wait for a lot of time if the number of jobs to be performed is more. For example if we take the scenario of sending mails to the user. Now for this if we have large number of users to whom we want to send a mail from our application so it will take a lot of time to get completed which no one will like to wait. So by using delayed jobs what we can do is we can execute the processes in the background and user wont have to wait till all the processes are completed. For that we will be using a gem called

gem 'delayed_job_active_record'

place this gem in your gemfile and run bundle install. Now after done with this we need to add the generator of this gem because active record actice records backend requires a job table in which the jobs will be stored in a queue. You can create the table by running the following command

rails generate delayed_job:active_record

and then run rake db:migrate Now when using this in development mode we need to set the queue_adapter in config/application.rb

config.active_job.queue_adapter = :delayed_job

with the help of this queue adapter we dont need to restart delayed Job every time we update our code in development. Now once done with this we will have to start the rake job in our console which will allow the jobs to run in the background without having the need to restart it again and again. We need to write this in console

rake jobs:work

This will start the rake job thread and will wait for a process or a task to come to it. Now last thing which we need to do is call the delay method where we actually need our jobs to be processed in background without affecting the current execution. Suppose oif you are sending a mail to all the users who have subscribed for a magazine so the users wont have to wait until the mail is sent to all the users. we will just add the delay method like this

NotificationMailer.delay.notification_email(email)

Here notification mailer is the name of the mailer and notification_email is the method through which the mail is being sent. Now the mail will be sent to all users in the background and the execution of the method wont be delayed.

Before_validation and after_touch callbacks in Rails

2017-09-26 09:00:40 +0000

Rails provide us with some pre-defined methods or hooks which can be invoked after or before the execution of a certain method in the object life cycle. Callbacks are called in certain moments of object’s life cycle which we will get to know in this blog. Today we will be studying about three callbacks as follows : before_validation As the name suggests, this method is called before validation of all the fields of the form. For example, there is a registration form which has an email field, so as soon as the user will fill the email field and submit the form before the value gets saved into the database we have to make sure that all characters in the email should be down case. So in this case, we will invoke a before_validation callback in which we will define a method to be called before the create method is called. In this method, we will convert the whole string into down case and after that, the create method will be called like this.

class Employee < ApplicationRecord
  
  before_validation :normalize_email, on: :create
 
  # :on takes an array as well
  
  def create
    ...
  end 
  protected
    def normalize_email
      self.email = email.downcase.titleize
    end
end

after_touch Whenever an object is being touched the after_touch callback is called . For example We create an employee object and as soon as we touch the object the after_touch callback is invoked.

class Employee < ApplicationRecord
  
  after_touch do |employee|
    puts "The object has been touched"
  end
end
 
>> e = Employee.create(name: 'Tom')
=> #<Employee id: 1, name: "Tom", created_at: "2013-11-25 12:17:49", updated_at: "2013-11-25 12:17:49">
 
>> e.touch
The object has been touched
=> true

So hope this article was helpful to understand both the callbacks.




subscribe via RSS