#Rails 4.2 #Ruby2.2 How to find association class and other info from an object and its association name

When I was working on a Rails project, I encountered a situation where I needed to find the association class of an association object. I have the object and its association name as inputs. How can I find the association class?

Suppose we have Student class that belongs to a school

class School
  has_many students
end

class Student
  belongs_to :school
end

and suppose so many other relations like this in our project.

So we have

s = Student.last
:school symbol 

I can use

s.school.class and s.school.class.name

But what if the school is blank? The result is ‘NilClass’ From the above code.

Basically for has_many associations now we get the class name as

"ActiveRecord::Associations::CollectionProxy"

because recently in new rails version a change of the Array of objects as associations to its own ‘CollectionProxy’ collections.

So we can use ‘ActiveRecord::Reflection::ClassMethods’ for finding all the association info.

Note that this Rails module is so useful to find all the association related information.

In the above situation we can use ‘reflect_on_association’ method for finding association reflection info. And it returns ‘ActiveRecord::Reflection’ Object.

In the most recent version of Rails, there has been a change where Array of objects as associations have been replaced with their own ‘CollectionProxy’ collections. As a result, we can now use ‘ActiveRecord::Reflection::ClassMethods’ to find all the association information we need. This module is extremely useful in finding all association-related information.

To find association reflection information in the situation described above, we can use the ‘reflect_on_association’ method. This method will return an ‘ActiveRecord::Reflection’ object.

http://api.rubyonrails.org/classes/ActiveRecord/Reflection/ClassMethods.html#method-i-reflect_on_association

Check the following code:

> s.class.reflect_on_association(:school)
=> ##}, @scope_lock=#
, @class_name="Topic", @foreign_key="school_id">

Set up capistrano deployment for Ruby On Rails

STEP 1:
Install capistrano gem

group :test, :development do
  gem 'capistrano'
end

Install capistrano with rvm

gem 'rvm-capistrano'

STEP 2:
Prepare your Project for Capistrano
Capify your project. The following command initialise your project with Capistrano.

$ capify .

STEP 3:
Do proper modificatons in Capistrano Recipe (config/deploy.rb)
http://guides.beanstalkapp.com/deployments/deploy-with-capistrano.html

Lets do the deployment for staging environment.
Create a ruby file under config/deploy/ folder named staging.rb
Copy the following content

set :domain, "mydomain.in"
role :app, domain
role :web, domain
role :db, domain, :primary => true
role :resque_worker, domain   # if you are using workers in your project, set role for them if needed
role :resque_scheduler, domain # if you are using workers in your project

set :deploy_to, "/home/my_deploy_path/"  # the deployment directory
set :environment, "staging"
set :rails_env, "staging"
set :branch, "staging"
set :previous_environment, "develop"

STEP 4:
Setup capistrano in deployment server

$ cap staging deploy:setup

This will Create folder structure that capistrano uses in the process.

Make sure that everything is set up correctly on the server by the command

$ cap staging deploy:check

Now you can see a message like:
“You appear to have all necessary dependencies installed”

Create shared/config folder in your deploy_to path
and copy database.yml and other config files as you written in the symlink_shared task in cap recipie (if any)

STEP 5:
Deploy your project:

cap staging deploy

How to categorise a blog posts data by month in Ruby On Rails

Suppose we have created a ‘BlogPost’ Model in Rails and it have the following fields in a blog post:

title – title of the blog post
posted_on – date posted
permalink – a permanent link of each blog post (act as a primary key)
publish – a boolean field which decides the post need to show or not

Lets write a method in ‘BlogPost’ Model to get a recent list of posts.
Pass a ‘months_old’ parameter to determine how much months old posts we wanted to list.
Just select the required columns to show the details of the post (by ‘:select => ‘). And Group each post by posted month.

  def self.get_recent_months_post(months_old)
    @blog_posts = where("publish = ? AND posted_on > ?", true, Date.today - months_old.months).all(:select => "title, posted_on, permalink", :order => "posted_on DESC")
    (@blog_posts.group_by { |t| t.posted_on.beginning_of_month }).sort.reverse
  end

We successfully written the method above. Now lets write a method to get the archives (old posts).

  def self.get_archives(old)
    @blog_posts = where("publish = ? AND posted_on  "title, posted_on, permalink", :order => "posted_on DESC")
    (@blog_posts.group_by { |t| t.posted_on.beginning_of_month }).sort.reverse
  end

How to create a migration file dynamically by meta programming in rails 4.0

If you want to create a migration file from a module written in lib file or somewhere from your ruby file and execute it, use the metaprogramming which can create a class or method dynamically. The following code snippet shows the methods we use and gives a better idea to create migration file dynamically.

def create_columns(tb_with_cols)
    add_columns = ""
    tb_name = tb_with_cols.keys.first
    columns = tb_with_cols.values.first
    columns.each { |c_name, c_type| add_columns << "\tadd_column(':#{tb_name}', :#{c_name}, :#{c_type})\n" }

    add_columns
 end

 def migration_file_content(tb_with_cols)
   cols = create_columns(tb_with_cols)
<<-RUBY
  class AddMissingColumnsToTable < ActiveRecord::Migration
     def change_table
    #{cols}
   end
 end
  RUBY
 end


 def write_content_to_file(path, content)
    File.open(path, 'w+') do |f|
      f.write(content)
    end
 end

Just call the method migration_file_content in your code. Pass the parameter tb_with_cols as a Hash, in which the key is the table_name and value is the columns that should be added to that table. Ex:

tb_with_cols = {:users => {:name => :string, :age => :integer, :address => :text} }
content = migration_file_content(tb_with_cols)
write_content_to_file("#{Rails.root}/db/migrations/', content)

After that call the method write_content_to_file with your new migration file path and the content from our migration_file_content method. 🙂

Rails way of creating a new full url with new parameters after removing old parameters from a url

If we have some keys and values and we just need to create a url with this data just pass the url and hash as a parameter to the following method.

def generate_url_with_params(url, params = {})
    uri = URI(url)
    uri.query = params.to_query
    uri.to_s
end

If you want to get rid of the parameters from a url use the following method.

  def generate_url_without_params(url, params = {})
    uri = URI(url)
    full_params = Rack::Utils.parse_query uri.query
    params.each do |key, val|
      full_params.delete key
    end
    uri.query = full_params.to_param
    uri.to_s
  end

How to implement a simple captcha in Rails using gem ‘simple_captcha’

Here it is, a simple captcha for Rails applications.

To set up, add the following line to your Gemfile

gem "galetahub-simple_captcha", :require => "simple_captcha"

Run rails generator

rails generate simple_captcha

Do db Migration

rake db:migrate -t

In your view file add

%= show_simple_captcha %

Add the following in yml file
en.yml:

en:
  simple_captcha:
    label: "Enter the above code"
    placeholder: "Enter here"

In controller just include captcha helpers module

class ApplicationController < ActionController::Base
  include SimpleCaptcha::ControllerHelpers
end

Use this code in the controller for the captcha validation

if simple_captcha_valid?
  do this
else
  do that
end

Details about pg gem error: Can’t find the ‘libpq-fe.h header when doing bundle in Rails

If you are getting errors like:

installing pdf-reader 1.3.3
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

/home/vagrant/.rvm/rubies/ruby-2.2.0/bin/ruby -r ./siteconf20150306-5919-1rr483p.rb extconf.rb
checking for pg_config... yes
Using config values from /usr/bin/pg_config
You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for building a client-side application.
You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for building a client-side application.
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.

when trying to install pg gem,
you are just missing some dependancy library related to libpq. Install the following package


$ sudo apt-get install libpq-dev

then do


$ gem install pg -v 'version-no'

then do


bundle install

Details about paperclip error: ‘Paperclip::AdapterRegistry::NoHandlerError’ when you use paperclip gem in Rails

When I was working with rails and paperclip I got this error.

Paperclip::AdapterRegistry::NoHandlerError
 = form_tag my_path, :method => :post do
  -------
  = file_field_tag "attachment" 
  -----
 

I submitted a form and it was not saving. There I found that the form sending a file too. I missed

:multipart => true 

option in the ‘form_tag’ when submitting the form. The form really not sening a file and paperclip not getting an attachment. So it throws this error.

 = form_tag my_path, :method => :post, :multipart => true do
  -------
  = file_field_tag "attachment" 
  -----

How to find index of records rendered by a partial with collection in Rails

Using render partial with collection how to find the index of the records?

Somewhere I found that someone is commented like,
“It seems this is an undocumented feature of rails.”

Anyway we can find this by using ‘recordName_counter’.

Render a partial with collection


= render :partial = > "person", :collection => @winners
Name: = person.name 

In Partial write


  Rank: = person_counter + 1
  Name: = person.name 

Result


Rank: 1 Name: Peter
Rank: 2 Name: Paul
Rank: 3 Name: Mary

Details about Rails paperclip error: ‘There was an error processing the thumbnail for paperclip-reprocess’

I got this error while working with paperclip. The project was stable and I have no idea why this error happens at this point of time.

[paperclip] An error was received while processing: #
[paperclip] An error was received while processing: #<Paperclip::PaperclipError: There was an error processing the thumbnail for paperclip-reprocess20110822-2281-19969sz

So I was lazy to fix the error, and find that I have no imagemagick installed in my new system. After installing ‘imagemagick’ it got fixed.

$ sudo apt-get update
$ sudo apt-get install imagemagick --fix-missing