Deploying a Rails app to a Sub URI

Recently I was working on a POC application. And I had to deploy that application to show a demo. Since it is a POC app I had to deploy it as a Sub URI of an existing app.

I modified the nginx conf file to set up the sub URI, based on the information from this doc. I have added passenger_base_uri option to the conf, but that was just starting the application from the sub URI. All the URLs in the application is using the base URL instead of the sub URI.

To make all the URLs from the application use the sub URI as the base URL, I had to add a scope in the routes:
SubUriApp::Application.routes.draw do
  my_draw = Proc.new do
   devise_for :users
  end

  if ENV['RAILS_RELATIVE_URL_ROOT']
   scope ENV['RAILS_RELATIVE_URL_ROOT'] do
     my_draw.call
   end
  else
   my_draw.call
  end
end
  

Read More...

Devise with token based authentication for API

Currently I am working on a project which has both API and mobile apps. I had to implement authentication for the API. Since I have to implement the authentication for the non browser clients (iOS, Android) I won't be able to use session based authentication. So I started implementing token based authentication. I am using Devise gem for token based authentication.

Devise is a flexible authentication solution for Rails applications. If you search in ruby tool box you will see that Devise is the most popular rails authentication plugin. Devise supports token based authentication too. Read More...

marked for destruction

Today I had gone through an issue, which got fixed by using the marked_for_destruction? method. This marked_for_destruction is part of Active Record Autosave Association module. Autosave Association module takes care of automatically saving associated records when their parent is saved. For more details see Auto Save Association .

In my project I have a model called Directory and it has many Categories. But I have to add a validation that there should be atleast one category associated with the directory. So in the directory model I added a validation in the after_save callback, which will check the count of Categories is greater that 0.

Read More...

Write a named scope to fetch the data sorted by distance using Geokit

Recently I had to work on a feature "As a User ISBAT see the Business sorted by distance". We are using Geokit gem for manipulating the location. And we have the models 'Business' has many 'Location's.

I had to fetch the businesses in the order of the distance of the locations from the origin. The origin is the point which we will pass to the method. Since this method should be part of a chained named scope, I had to implement this as a named scope.

After done some searching I found a useful link from pivotallabs. At the end there is one comment from Keith:

named_scope :within, lambda{|o, d|
 origin = o
 distance_sql = self.distance_sql(origin)
 within = d
 {:select => "*, #{distance_sql} as distance",
  :conditions => "#{distance_sql} <= #{within}", 
  :order => 'distance asc'}}


This code helped me to create a named scope which will fetch the businesses in the order of the distance.

The test also passed for this named scope. But in the controller, where I am using this named scope along with other named scopes i,e, chained named scope, the named scope was not working as expected. It was throwing MySql Error with message "distance is undefined".

After done with some searching I found the link which explains that in chain named_scopes only conditions will get added, and selects will get ignored.

Then I tried by changing the 'distance' variable with the distance_sql as the order value. And it worked:

named_scope :by_location, lambda{|origin, within|
 distance_sql = Location.distance_sql(origin)
 {:select => "*",
  :conditions => "#{distance_sql} <= #{within}", 
  :order => '#{distance_sql}', :joins => :locations }}


Read More...

acts_as_taggable_on gem have issue with after_save callback

Today I had spent a lot of time fixing an after_save callback issue related with acts_as_taggable_on gem. We're associating keyword tag to a model using the following command:

acts_as_taggable_on :keywords

And we've a after_save call back in that model which uses the updated keywords. But the issue was in the callback, if you reload the object you will lose the new keywords associated with it, because the keywords are not yet saved.

Then I Googled about this issue and found the following blog which helped me to solve the issue: http://blog.romanandreg.com/post/176944361/activerecord-callbacks-acts-as-taggable-gotcha I tried with the update_tags mentioned in the blog, but with the latest acts_as_taggable_on gem this fix is not working. Then I gone through the code of acts_as_taggable_on gem, and in core.rb I found the following line:

after_save :save_tags

Then I tried calling save_tags from my callback method. Thats it! It got fixed!!

Read More...