Pages

Thursday, January 30, 2014

API Upload with CarrierWave

 I want to share a quick snippet with regards to a problem I had a few months ago: How to upload a picture/file to a Ruby on Rails project, which is utilizing CarrierWave to handle the upload mechanism, by utilizing the direct POST call.
With this comes at least two challenges:
  • You cannot insert a file directly into a JSON object;
  • CarrierWave does not support uploading a file which is not uploaded using a form object.
Solving the first problem is almost trivial, you simply encode the file into Base64 and pass it along, but the second problem requires a little more work. What I did to solve it was to decode the Base64 string into a temp file, and then create a new uploaded file from that temp file.

Saturday, January 11, 2014

Fixing readline for the Ruby on Rails console

have begun trying out the Ruby on Rails framework. While doing so I got stuck at a very early stage in thedocumentation.
$ rails console
/home/tobias/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/irb/completion.rb:9:in `require': no such file to load -- readline (LoadError)
from /home/tobias/.rvm/rubies/ruby-1.9.2-p18080/lib/ruby/1.9.1/irb/completion.rb:9:in `<top (required)>'
from /home/tobias/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.9/lib/rails/commands/console.rb:3:in `require'
from /home/tobias/.rvm/gems/ruby-1.9.2-p180/gemsems/railties-3.0.9/lib/rails/commands/console.rb:3:in `<top (required)>'
from /home/tobias/.rvm/gems/ruby-1.9.2-p180/gems/railties-3.0.9/lib/rails/commands.commandsrb:20:in `require'
from /home/tobias/.rvm/gems/ruby-1.9.2-p180/gems/railsilties-3.0.9/lib/rails/commands.rb:20:in `<top (required)>'
from scriptt/rails:6:in `require'
from script/rails:6:in `<main>'
The problem is that Ruby is somehow not cofigured to load the readline library and thus cannot run its console. This is a downside of using a language specific package manager, seperate from your operating system's package manager.

Friday, January 10, 2014

Rails- :dependent => :destroy VS :dependent => :delete_all

In rails guides it's described like this:
Objects will be in addition destroyed if they’re associated with :dependent => :destroy, and deleted if they’re associated with :dependent => :delete_all
But what's the difference between being destroyed and being deleted?
The difference is with callback.
The :delete_all, made directly in your application the delete by SQL :
DELETE * FROM users where compagny_id = XXXX
With the :destroy, there are an instantiation of all of you children. 
So, if you can't destroy it or if each has their own :dependent, its can be called.

Use after_commit instead of active record callbacks to avoid unexpected errors

AR callbacks after_create/after_update/after_destroy to generate background job etc are useful, but these callbacks are still wrapped in database transaction, and you may probably get unexpected errors on production servers.
Before It’s common to generate a background job to send emails like
class Comment < ActiveRecord::Base
  after_create :asyns_send_notification
  def async_send_notification
    Notifier.send_new_comment_notification(self).deliver
  end
 handle_asynchronously :async_send_notification
end

# It looks fine that comment record passed to delayed job and then delayed job will fetch this
#comment and then post on which this comment has been made and a notification will
#send via email to the author of that post. Right?
You won’t see any issue in development, as local db can commit fast. But in production server, db traffic might be huge, worker probably finish faster than transaction commit. e.g
  1. main process
  2. worker process
  3. BEGIN
     INSERT comment in comments table
     # return id 10 for newly-created notification
     SELECT * FROM notifications WHERE id = 10
     COMMIT
    
In this case, the worker process query the newly-created notification before main process commits the transaction, it will raise NotFoundError, because transaction in worker process can’t read uncommitted notification from transaction in main process.
Refactor
So we should tell activerecord to generate notification worker after notification insertion transaction committed.
class Comment < ActiveRecord::Base
after_commit :asyns_send_notification,:on => :create  # This is the main point of the whole thing.

  def async_send_notification
    Notifier.send_new_comment_notification(self).deliver
  end
 handle_asynchronously :async_send_notification
end
Now the transactions order becomes
  1. main process
  2. worker process
  3. BEGIN
     INSERT comment into comments_table
     return id 10 for newly-created notification
     COMMIT
     SELECT * FROM notifications WHERE id = 10
    
Worker process won’t receive NotFoundErrors any more. :)
For More Details visit http://www.codebeerstartups.com

Thursday, January 9, 2014

Ruby Way - Swap two variables

In Ruby, you can easily swap values of two variables without the need for a temporary third variable:
x,y = y,x
This is called ‘Parallel Assignment’.
Can’t believe it? I had to test it myself, too:
$ irb
>> x = 5
=> 5
>> y = 10
=> 10
>> x,y = y,x
=> [10, 5]
>> x
=> 10
>> y
=> 5

3 ways to invoke a method in Ruby

You can use following methods to invoke any method in ruby -

object = Object.new

1. The dot operator (or period operator)
puts object.object_id
 #=> 282660

2. The Object#send method
puts object.send(:object_id)
 #=> 282660

3. The method(:foo).call
puts object.method(:object_id).call
 #=> 282660

Wednesday, January 8, 2014

Ruby - A Duck Typed Language

Duck Typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface. The name of the concept refers to the duck test, attributed to James Whitcomb Riley , which may be phrased as follows:
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
In duck typing, one is concerned with just those aspects of an object that are used, rather than with the type of the object itself. For example, in a non-duck-typed language, one can create a function that takes an object of type Duck and calls that object's walk and quack methods. In a duck-typed language, the equivalent function would take an object of any type and call that object's walk and quack methods. If the object does not have the methods that are called then the function signals a run-time error. If the object does have the methods, then they are executed no matter the type of the object, evoking the quotation and hence the name of this form of typing.

Ruby - Format dates with suffix, like “Sun Oct 5th”

Use the ordinalize method from 'active_support'.
>> time = Time.new
=> Fri Oct 03 01:24:48 +0100 2008
>> time.strftime("%a %b #{time.day.ordinalize}")
=> "Fri Oct 3rd"
Note, if you are using IRB with Ruby 2.0, you must first run:
require 'active_support/core_ext/integer/inflections'

Tuesday, January 7, 2014

Multiple submit buttons for the same form in Rails

You can create multiple submit buttons and provide a different value to each:
<% form_for(something) do |f| %>
    ..
    <%= f.submit 'A' %>
    <%= f.submit 'B' %>
    ..
<% end %>
This will output:
<input type="submit" value="A" id=".." name="commit" />
<input type="submit" value="B" id=".." name="commit" />
Inside your controller, the submitted button's value will be identified by the parameter commit. Check the value to do the required processing:
def <controller action>
    if params[:commit] == 'A'
        # A was pressed 
    elsif params[:commit] == 'B'
        # B was pressed
    end
end
However, remember that this tightly couples your view to the controller which may not be very desirable.

Not Equal support for Active Record queries in Rails 4

The Active Record query interface for the most part abstracts SQL from the developer. However, there is a condition that always requires using pure string conditions in awhere clause: <> or !=, depending on the database. Starting in Rails 4, query method not has been added to rectify this.

Example

Let's look at an example of executing the new not query method. First we will look at how it was done in Rails 3, and then look at how Rails 4 handles the same problem. All examples will be querying against an Article model with a title field. The examples below will be using a SQLite database.

The Rails 3 Way

Article.where("title != ?", params[:title])

The Rails 4 Way

To use the new query method, it must be chained to a where clause with no arguments:
Article.where.not(title: 'Rails 3')
# >> SELECT "articles".* FROM "articles" WHERE ("articles"."title" != 'Rails 3')
The not query method can also accept an array to ensure multiple values are not in a field:
Article.where.not(title: ['Rails 3', 'Rails 5'])
# >> SELECT "articles".* FROM "articles" WHERE ("articles"."title" NOT IN ('Rails 3', 'Rails 5'))

Monday, January 6, 2014

New HTML5 Form Input Helpers for Rails4

In this post, we are going to take a look at the new HTML5 Form Helpers being added into Rails 4. While we are only covering the model object helper versions that are used with form_for, each form helper below also has a corresponding tag helper. For example, if we are talking about week_field, there is a tag helper week_field_tag that can be used withform_tag.

week_field

The week_field form helper creates an input of type "week", that sets a week without any timezone information. A week is represented by four digits for the year, followed by -W, and ending with two digits representing the week number. For example, the current week of this post would be 2012-W50.
The week_field form helper accepts three options: :min:max, and :step:
  • :min: The minimum acceptable value
  • :max: The maximum acceptable value
  • :step: The acceptable value granularity
Here is an example of a week_field being set with optional minimum and maximum week constraints:
<%= f.week_field :week,
  min: Time.zone.today.beginning_of_year,
  max: Time.zone.today.end_of_year %>

Register your own flash types - Rails 4

In Rails 3, the ability to set flash parameters :notice and :alert in a controllerredirect_to call was added. Along with this change,ActionController::Base#notice andActionController::Base#alert were added as convenience accessors, which mapped to flash[:notice] and flash[:alert] respectively.
To set a custom flash type in your controller, you would have add the key/value pair to the controller flash hash, or you could also pass a hash to the optional :flashoption in redirect_to.
As of Rails 4, developers will have the ability to register their own flash types by using the new ActionController::Flash.add_flash_types macro style method.

The Rails 3 Way

Here is an example of setting a custom error flash type in Rails 3:
# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    ...
    flash[:error] = "An error message for the user"
    redirect_to home_path
  end
end

# app/views/home/index
<%= flash[:error] %>

The Rails 4 Way

Here is the same example as above, using Rails 4:
# app/controllers/application_controller.rb
class ApplicationController
    ...
  add_flash_types :error, :another_custom_type
end

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    ...
    redirect_to home_path,
      error: "An error message for the user"
  end
end

# app/views/home/index
<%= error %>

Saturday, January 4, 2014

Migration to rename an ActiveRecord model and its table in Rails

In Rails 3.1+ ActiveRecord::Migration::CommandRecorder knows how to reverse rename_table migrations, so you can do this:
class RenameOldTableToNewTable< ActiveRecord:Migration
    def change
        rename_table :old_table_name, :new_table_name
    end 
 end
You need to rename the model declaration files manually.

Routing Concerns - Rails 4

The Rails config/routes.rb file encapsulates all the mappings from URLs to controller actions. Over the years, helpful additions have been added to slim this file down so that as developers, we can stop repeating ourselves. One example of this was the routing method resources, which maps four named routes to seven controller actions based on the HTTP request method.
As of Rails 4, routing concerns have been added to the router. Routing concerns allows you to declare common routes, which can be mixed into other resources and routes.

Example

A common example of duplication in the config/routes.rb file happens when a polymorphic association is nested under a parent resource.

Friday, January 3, 2014

nil vs empty vs blank in Ruby on Rails

.nil?
.nil? can be used on any object and is true if the object is nil.
.empty?
.empty? can be used on strings, arrays and hashes and returns true if:
  • String length == 0
  • Array length == 0
  • Hash length == 0
Running .empty? on something that is nil will throw a NoMethodError.
.blank?
That is where .blank? comes in. It is implemented by Rails and will operate on any object as well as work like .empty? on strings, arrays and hashes.
nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
.blank? also evaluates true on strings which are non-empty but contain only whitespace:
"  ".blank? == true
"  ".empty? == false
Rails also provides .present?, which returns the negation of .blank?.

Rename a Database column using Rails migration

You need to create a separate migration to do this.

rails g migration FixColumnName

class FixColumnName < ActiveRecord::Migration
  def change
    rename_column :table_name, :old_column, :new_column
  end
end

If you happen to have a whole bunch of columns to rename, or something that would have required repeating the table name over and over again.
rename_column :table_name, :old_column1, :new_column1
rename_column :table_name, :old_column2, :new_column2
...
You could use change_table to keep things a little neater.
class FixColumnNames < ActiveRecord::Migration
  def change
    change_table :table_name do |t|
      t.rename :old_column1, :new_column1
      t.rename :old_column2, :new_column2
      ...
    end
  end
end