Difference between update_attribute, update_attributes and update_column in ruby on rails

update_attribute: This is used when need to update an attribute with validations(false) & save(false).

  • validations skipped.
  • callbacks are invoked
  • updated_at default rails column gets updated
  • all dirty attributes get updated.

ex: Object.update_attribute(:field, “value”)

update_attributes: This can be used to update many attributes of an object together  or an hash with validations(true) & save(true). If object is not correct it will fail.

  • validations are invoked.
  • callbacks are invoked
  • updated_at default rails column gets updated

ex: Object.update_attribute(:field, “value”)
Object.update_attributes(:field1 =>”value1″, :field2 => “values”)
Object.update_attributes(params[:model])

update_column:  This is used when need to update an attribute with validations(false) & save(false). This works as update column query in sql without calling save.

  • validations are skipped.
  • callbacks are skipped
  • updated_at default rails column DO NOT get updated.

 

Similarly update_columns(:field => value) can be used to update multiple columns without save.

.attributes property: use this on model to update attributes without saving to database.

ex:  @user= User.new(:first_name = ‘name’, :last_name=>’surname’)

@user.attributes = (:first_name = ‘Aakash’, :last_name=>’Sharma’)

@user.save

 

 

 

 

 

Advertisements

Converting an array into active record in rails

Converting an array into active record in rails

So this is a common requirement which every one of us have to face once a while.
In my project I was getting the array of result from a modal method i.e backup_projects. Now to apply sorting and pagination I have to convert it into rails active record.

As I could have applied sorting on active records only. So I came across a way as shown below.

     project = Project.backup_projects
      project.map{|i| i.id}
      @projects = Project.where(:id => project)
@projects was an active record thus and served my purpose.

Creating a symlink/symbolic link in Rails

  • symbolic links: Refer to a symbolic path indicating the abstract location of another file

    Syntax: ln -s {target-filename} {symbolic-filename}

    For example create symlink for /home/work/index.rb as/home/Aakash/index.rb, enter the following command:

    ln -s /home/work/index.rb /home/Aakash/index.rb
    On doing ls -l , it shows output as

    lrwxrwxrwx 1 Aakash  Aakash    16 2013-09-20 10:47 index.rb -> /home/Aakash/index.rb
    
    To simply delete the link
    Use rm {link-name}
    i.e  rm index.rb
  • Rails way of creating a Symlink while using Capistrano recipes is as :
    after “deploy:update_code” do # Run bundle install
    run "ln -nfs #{shared_path}/public/techease #{release_path}/public/techease"
    end

    -n–no-dereference
             treat destination that is a symlink to a directory as if it were a normal file
    -f–force
           remove existing destination files
    -s–symbolic
           make symbolic links instead of hard links

How to update Active Record from rails console

How to update Active record from back-end using rails console

While working on rails console I figured out SQL way to update an active record from rails console.
So I have to update flag value of a field ’email_dangling’ to ‘0’

so Steps are as:

1. bundle exec rails c production

2. ActiveRecord::Base.connection.execute ‘update emails set email_dangling = 0 where id = 1234’

And its done!

ORA-01704 : string literal too long

Change in Column data type from String to text in Rails

So this is something tricky I came to know while working on one of the project on Ruby on Rails.  I am using Oracle as the database. I have a plan_template model, which has an attribute ‘value’ whose data type is string with limit as 4000 as :

 t.string  :value, :limit => 4000

So the requirement was to change its limit. So i came up with an idea of changing it to text.

I simply ran the migration as bundle exec rails destroy migration ChangeColumnInPlanElements

class ChangeColumnInPlanElements < ActiveRecord::Migration
def self.up
change_column :plan_elements, :value, :text
end

def self.down
end
end

& on doing rake  db:migrate I came across an error as :

== ChangeColumnInPlanElements: migrating =====================================
— change_column(:plan_elements, :value, :text)
rake aborted!
An error has occurred, all later migrations canceled:

OCIError: ORA-22859: invalid modification of columns: ALTER TABLE “PLAN_ELEMENTS” MODIFY “VALUE” CLOB
stmt.c:235:in oci8lib.so

Then browsing on net i came to know When we try to modify a datatype from varchar2(4000) to Clob in a Oracle table, we get this error.

So Then I came up with the approach to do this it is a four steps task :

ALTER TABLE SCHEMANAME.TABLENAME ADD NEWCOLUMN CLOB;
UPDATE SCHEMANAME.TABLENAME SET NEWCOLUMN = OLDCOLUMN;
ALTER TABLE SCHEMANAME.TABLENAME drop COLUMN OLDCOLUMN;
ALTER TABLE SCHEMANAME.TABLENAME rename COLUMN NEWCOLUMN TO OLDCOLUMN;

which is equivalent to
1. Add a  temporary column with type as text(CLOB)
2. Update all the records and copy text from value column to temporary column
3. Remove value column
4. Rename temporary column to value

so then I modified my migration file as

class ChangeColumnInPlanElements < ActiveRecord::Migration

def self.up
add_column :plan_elements, :value_temp, :text
PlanElement.all.each do |et|
et.update_attribute(“value_temp”, et.value)
end
remove_column :plan_elements, :value
rename_column :plan_elements, :value_temp, :value
end
def self.down
end
end

And it worked like a charm for me…. !

Actionmailer, rake task & Scheduler

Actionmailer, rake task & Scheduler

Please follow the below steps to implement an actionmailer in your app, create a rake task to call the mailer function and schedule that particular task to run on a specific time.
1. To Implement action mailer in rails~3:
Action mailer feature of rails allows to send emails. A mailer model and a view is required for  the same.
In this tutorial, we would send the email using gmail service.
Step 1:  Create a demo project.
               rails new mail_project
Step 2:  Create a User model.
              rails generate scaffold  User name:string email:string
Step 3:  Create a mailer model
              rails generate mailer UserMailer
              create  app/mailers/user_mailer.rb
              invoke  erb                                             
              create    app/views/user_mailer                 
              invoke  test_unit                                      
              create    test/functional/user_mailer_test.rb
               
              
Step 4: Now, we  need to configure the SMTP mail settings in development.rb.
          in config\environments\development.rb
          config.action_mailer.default_url_options = { :host => ‘localhost:3000.com’ }
          config.action_mailer.smtp_settings =  {
          :enable_starttls_auto => true,
          :address        => ‘smtp.gmail.com’,
          :port           => 587,                                   # default port for gmail.
          :domain         => ‘your.domain.com’,
          :authentication => :login,
          :content_type   => “text/html”,
          :user_name      => ‘youremail@gmail.com’,
          :password       => ‘password’
                                                                  }
Note:  To deploy the app on heroku, edit the settings in production.rb
Step 5: Edit the mailer and create your mail method.
            in app/mailers/user_mailer.rb , lets define a method demo_mail
            def demo_mail(user)
            mail(:from => “Testmail@demo.com”,
                     :to => user.email
                     :subject => “Greet User”)
            end
Note: To add pictures as inline attachment/logo in rails 3, use as:
 attachments.inline[‘rails.png’]=File.read(‘app/assets/images/rails.png’)
Step 6: Create a view template to render the view, create the view with the same method name which we used in our user_mailer.rb.
i.e views/user_mailer/demo_mail.html.erb
  <!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
  <html lang=”en”>
  <head>
  <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
  <style type=”text/css” media=”screen” class = “content”>
   h3 { color: #f00; }
   ul { list-style: none; }
  </style>
  </head>
  <body>
  <strong><p>Dear <%= @user %>,</p></strong>
  <p>Hello, How are you ?</p>
  <%= image_tag attachments[‘rails.png’].url % >
  </body>
  </html>
Note :  We have use attachments.url in image_tag to display the inline attachment.
Step 7: Add a line to call the method demo_mail of UserMailer.
        –  this could be done from a task or from some method of User controller.
           UserMailer.demo_mail(user).deliver!
Points to ponder:
1. While uploading your app on heroku, make sure that you have done smtp mail setting in file production.rb
2. Inline attachment might be block from your office network. So you can check them on gmail network.
3. Apart from that there might be few more problem on restricted network.

2. How to Create a rake task:

Step 1: Introduction to rake
– rake is a task which is created at /lib/tasks with .rake extension. Doing this, rails picks it up  automatically and make it available to you.
ex: demo.rake
– you can see your task listed by doing rake -T
– to run your task:
  rake demo
Step 2: Writing a task on mailer created above
          in lib/tasks/demo.rake
          
      namespace :demo do
     desc “This is to send an email to users”
     task(:mail_users => :environment) do
     UserMailer.demo_mail(user).deliver!    # as we saw in Step7 above
     end
     end
Similarly, many tasks can be created in this file and they all would be listed with description.
Step 3: To run/schedule task
this task can be run as rake demo:mail_users
or else we can schedule our task to run later.(Covered in section 3 of this blog)

3. How to schedule a rake task:

To schedule a task demo of ‘rufus-scheduler‘ is done here.
Otherwise there are so many ways to schedule a task. ex clockwork and so many.
Step 1: Introduction to rake
rufus-scheduler is a Ruby gem for scheduling pieces of code (jobs). It understands running a job AT a certain time.
Step 2:  Add Gem and install it
add gem ‘rufus-scheduler’ to your gemfile and run bundle install.
gem install rufus-scheduler
Step 3: Create a task_scheduler.rb file in /config/initializers
Schedule the task like:
require ‘rubygems’
require ‘rake’
require ‘rufus/scheduler’
scheduler = Rufus::Scheduler.start_new
scheduler.every ’15m’ do
system ‘bundle exec rake demo:mail_users’
end
# this will trigger the mail_users task every 15 minutes.
Note: Similarly, task can be schedule every hour, daily, weekly or monthly basis

Hope there might be something for you in this blog !!

The Essence of Agility

                                        The Essence of Agile

 

 

Agenda:

 – What is Agile?
 – Agile over ancient models
 – My first encounter with Agile
 – Process Learning & Improvement
 – Common mistakes and fall-backs

 What is Agile?

  Agile Development: Continuous integration as ‘Only change is constant’

–  Individuals & Interactions over process and tool.
–  Working Software over comprehensive documentation.
–  Customer collaboration over contract negotiation
–  Responding to change over following a plan

 

Agile over ancient models

Waterfall Model:

  – Understanding & writing Specifications
  – Performing in-depth analysis and design
  – Developers should follow the specifications
  – Testing after implementation
  – Delivering the finished result to user

 

Agile Model:

   – Self-organized & self-driven team
   – Collective responsibility
   – Smart work rather than hard work
   – Face-to-face conversation.
   – Deliver working software frequently
   – Welcome Changing requirements
   –  Satisfy the Customer rather than negotiations.

 

My first encounter with Agile

It was the First encounter with Agile; we practiced many ways in our project which was again a good learning on Agile.

First basic requirement of Agile is be adaptive and be ready for the Change.

– Used Mingle, Story Boards, Charts (Kanban) for sprint planning.
–  Story weight age – Fibonacci (as per time or difficulty)
– Retrospectives (Some Retros can be done even on lunch table)
– Pair Programming, TDD,
– Short Demos and interactive discussions
– Continuous Integration

 If you are following Agile then ‘CHANGE IS INEVITABLE’


Process Learning & Improvements 

As a newbie, few interesting learning experiences which I learnt through are:

 MOSCOW Principle: Integrating your requirements in 4-5 parts mainly

                                       – Must have
                                       – Should have
                                       – Could have
                                       – Would have
                                       – & nice to have ()

 And thus prioritize your stories accordingly.

 SCRUMMING the Scrum:

 – Change something daily to improve something i.e

        – may be cleaning your code.
        – cleaning your work place.
        – may be improving your test coverage.
        – may be some small enhancement in UI apart from routine work.

Few common mistakes & practices might lead agility to fragility. . To avoid that few key requirements are as:

Regular Retrospectives – indulge transparency in team & business people.

Daily Standup
Estimation of story points – proper estimation of stories.
Short term Demos – can minimize your iterations.

 

In short  my learning is Agility comes from within by adopting it more in you !