Wednesday 25 November 2015

How to use view helpers in my ActionMailer views?

If you want to use a helper in mailers:

You can just add in your mailer
helper ApplicationHelper
or whatever helper you need
class MyMailer < ApplicationMailer
helper ApplicationHelper
end

Determine if asset exists?

Determine if asset exists?

 Rails.application.assets.find_asset("cards/header.png")
 => #<Sprockets::Asset:1d346d0 "file:///home/saritha/sites/new_app/app/assets/images/cards/header.png?type=image/png&id=d571d3707e9e08e6527f5c6049742fc7a13672b43ebbcffe625c8986d31c3759">

Rails.application.assets.find_asset 'notthere.png'
 => nil

Rails.application.assets.find_asset("cards/header.png").present?
=> true

Rails.application.assets.find_asset("cards/notthere.png").present?
=> false

Let’s play with ruby function to remove all white spaces.


1.9.3p125 :001 > a = “Miasa Pride”
 => “Miasa Pride”
1.9.3p125 :002 > a.strip
 => “Miasa Pride”
1.9.3p125 :006 > a.gsub(/\s+/, “”)
 => “MiasaPride”
1.9.3p125 :007 > b = ” Miasa Pride “
 => ” Miasa Pride “
1.9.3p125 :008 > b.gsub(/\s+/, “”)
 => “MiasaPride”
1.9.3p125 :009 > c = ” Miasa@Pride “
 => ” Miasa@Pride “
1.9.3p125 :010 > c.gsub(/\s+/, “”)
 => “Miasa@Pride”
2.2.2 :019 > a.delete("")
 => "Miasa Pride" 
2.2.2 :020 > a.delete(" ")
 => "MiasaPride" 
2.2.2 :021 > 
Cheers….!!!!!!!!

Monday 2 November 2015

How do I pass a hash with hidden_field or hidden_field_tag:



<%= text_field 'item_quantity', item.id, :value => item.quantity %>

then parameters:

"item_quantity"=>{"56372b6ce5d9832c6f000002"=>"1", "5637442ae5d9832c6f00002b"=>"5"}

Wednesday 28 October 2015

how to access controller method as helper_method?


Declare a controller method as a helper. For example, the following makes the current_user controller method available to the view:

class ApplicationController < ActionController::Base
helper_method :current_user

def current_user
@current_user ||= User.find_by_id(session[:user])
end
end

In a view:

Welcome, <%= current_user.name %>

Wednesday 21 October 2015

creating instance based on model name :



var_name = Admin::User.model_name.param_key

# var_name is admin_user

to make admin_user as instance variable:

instance_variable_set("@#{var_name}", Admin::User.last)

now,

@admin_user give you a last record of Admin::User model.

wow...........

Friday 16 October 2015

Use model association in create:


Use model association in create:

class BlogsController < ApplicationController
def create
@blog = Blog.new(params[:blog])
@blog.user_id = current_user.id
@blog.save
end
end

In this example, user_id is assigned to @blog explicitly. It's not too big problem, but we can save this line by using model association.

class BlogsController < ApplicationController
def create
@blog = current_user.blogs.build(params[:blog])
@blog.save
end
end

class User < ActiveRecord::Base
has_many :blogs
end

We define the association that user has many blogs, then we can just use current_user.blogs.build or current_user.blogs.create to generate a blog, and the current_user's id is assigned to the user_id of the blog automatically by activerecord.

Select specific fields for performance:

Select specific fields for performance:

database schema fo user model:

class User.rb
#fields
field :email, type: String, default: ""
field :encrypted_password, type: String, default: ""
field :first_name, type: String
field :last_name, type: String
field :age, type: Integer
field :sign_in_count, type: Integer, default: 0
field :current_sign_in_at, type: Time
field :last_sign_in_at, type: Time
field :current_sign_in_ip, type: String
field :last_sign_in_ip, type: String
field :provider, type: String
field :uid, type: String
field :description, type: String
end

The users index page displays 10 posts. At the beginning, I used

class UsersController < ApplicationController
  def index
    @posts = User.paginate(:page => params[:page])
  end
end

sql query:

SELECT * FROM users  LIMIT 0, 10

It was very slow when the user has huge description.

In rails there is a method "select" to fetch specific fields, Here I give you the way.

class User
  INDEX_COLUMNS = column_names - ['description', 'encrypted_password', sign_in_count', 'current_sign_in_at', 'last_sign_in_at', 'current_sign_in_ip', 'last_sign_in_ip']
end

class PostsController < ApplicationController
  def index
    @posts = Post.select(Post::INDEX_COLUMNS).paginate(:page => params[:page])
  end
end

Here rails tells database fetch only name, email, age, uid

SELECT name, email, age, uid, description FROM `posts` LIMIT 0, 10

It is faster than before and use less memory.

NOTE:
You should not select specific fields if you use memory object caching system, such as memcache.

Wednesday 14 October 2015

write a helper method to generate link_to with in li


application_helper.rb

def link url_path, class_name, title
content_tag :li do
link_to title, url_path, title: title, class: 'class_name'
end
end

usage:

in app.html.erb file:

<ul>
<%= link users_path, 'user', 'user' %>
</ul>

that's it....

Convert BSON::ObjectId to string and string to BSON::ObjectId


Convert BSON::ObjectId to string:
1.9.3-p125 :080 > profile = Profile.last.id
=> BSON::ObjectId(‘4fe969dd79216d0af9000002’)
1.9.3-p125 :083 > profile_id = profile.to_s
=> “4fe969dd79216d0af9000002”

Convert string to BSON::ObjectId:
1.9.3-p125 :084 > BSON::ObjectId.from_string(profile_id)
 => BSON::ObjectId(‘4fe969dd79216d0af9000002’)

Wednesday 7 October 2015

Use of scope with validates_uniqueness_of rails

There is a :scope option that you can use to specify other attributes that are used to limit the uniqueness check:

Eg: I want to validate name should be unique with in the section

validates_uniqueness_of :name, scope: :section_id

Thursday 10 September 2015

Recapture gem integration steps:


1, add recaptcha gem to gemfile.
gem 'recaptcha', :require => 'recaptcha/rails'
2, the run bundle
bundle install
3, register an app in google recaptcha with following link
https://www.google.com/recaptcha/admin
4, add recaptch.rb with following code in instializers
Recaptcha.configure do |config|
  config.public_key  = 'xxxxxxxxxxxxxxxxxxxc' #site key
  config.private_key = 'xxxxxxxxxxxxxxxy' #secreat key
  config.api_version = 'v2'
end
5, add below tag in sign up form
<%= recaptha_tags %>
6, add below code in regitsration create method
def create
if verify_recaptcha
super
else
build_resource(sign_up_params)
flash.now[:alert] = 'There was an error with the recaptcha code below. Please re-enter the code.'
render :new
end
end

that's it..

Friday 4 September 2015

Validates Email Field From Controller



class User
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

if valid_email?(user.email)
user.save
redirect_to root_url, :notice => 'Good email'
else
flash[:error] = 'Bad email!'
render :new
end

private
def valid_email?(email)
email.present? &&
(email =~ VALID_EMAIL_REGEX) &&
User.find_by(email: email).empty?
end
end

Thursday 3 September 2015

Sublime text2 package control install:



Go to link
https://packagecontrol.io/installation
Copy python code for sublime text2/3

ctrl+`  --> To open console.

Paste python code, then press enter

Restart sublime.

Ex: To install trailing spaces.

Then install package Trailing spaces(like package control)

ctrl+shift+p search for package control press enter.

ctrl+shift+p search for trailing space press enter.

Monday 31 August 2015

Better Errors To Open In Sublime:


group :development, :test do
gem 'better_errors'
gem 'binding_of_caller'
  gem 'meta_request'
end

$bundle

add better_errors.rb in /config/initializers then add bellow code:

if defined? BetterErrors
  BetterErrors.editor = proc { |full_path, line|
    full_path = full_path.sub(Rails.root.to_s, "/home/saritha/sites/testproj")
    "subl://open?url=file://#{full_path}&line=#{line}"
  }
end

To handle with firefox:

1. First of all download and install sublime url handler patch to handle the url with line number. Download sublime-url-handler.
from https://github.com/algorich/sublime-url-handler/archive/master.zip
2. Goto to development.rb file and add BetterErrors.editor = :sublime

3. Goto firefox and type about:config in url and hit enter

4. Right click and create new property with boolean type with name " network.protocol-handler.expose.subl" set "False".

5. Restart Firefox.

6. Run your rails app and get the error link page, click on error link it will ask open open with if sublime-url-hanlder is shown here well done choose and cheers if not shown than give your sublime executable path here and done.

you can add https://chrome.google.com/webstore/detail/railspanel/gjpfobpafnhjhbajcjgccbbdofdckggg to chrome..this will help in detail work flow..

Create custom rake tasks:

Rake Tasks:

Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and .rake files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.

It is most often used for administration level tasks that can be scripted. The benefit to using Rake over Make or similar, is that it is a Ruby tool and can interface with your RoR app natively, so Models, data constraints and business rules are all available for use.

1. create a rake file

say lib/tasks/product.rake

another way to create a rake file:

$rails g task my_namespace my_task1 my_task2
$ create lib/tasks/my_namespace.rake
It will generate scaffold for our new rake task: >lib/tasks/my_namespace.rake

namespace :my_namespace do
  desc "TODO"
  task :my_task1 => :environment do
  end

  desc "TODO"
  task :my_task2 => :environment do
  end
end

It is awesome! And now you can write here your code for new rake tasks.

Let’s make sure these rake tasks are exist and we are able to use them:

$ rake -T | grep my_namespace
rake my_namespace:my_task1  # TODO
rake my_namespace:my_task2  # TODO

To upload products from csv using rake task:
require 'rubygems'
require 'csv'
namespace :product do
desc "To Upload products"
task :upload , [:file] => :environment do |task, args|
CSV.foreach(args[:file]) do |row|
puts row[0] + "creating.."
if row[0].present?
Product.create(row[0])
else
puts "Here is an empty row!"
end
end
end
end

$rake --tasks
$rake product:upload[file] #To Upload products

rake product:upload['/home/saritha/Downloads/270815 New Registrations.csv']

To run rake tasks in production mode:

$rake product:upload['/home/saritha/Downloads/270815 New Registrations.csv'] RAILS_ENV=production

Friday 21 August 2015

How to get rails process id


ps aux|grep rails

ps --> process status

a --> show processes for all users
u -->  display the process's user/owner
x --> also show processes not attached to a term

By the way, "man ps" is a good resource.

What is the parent class of all classes in Ruby?



2.2.2 :001 >  Class.superclass
 => Module
2.2.2 :002 > Module.superclass
 => Object
2.2.2 :003 > Object.superclass
 => BasicObject
2.2.2 :004 > BasicObject.superclass
 => nil

===> "BasicObject" is the parent class of all classes in Ruby.

2.2.2 :001 >  BasicObject.class
 => Class
2.2.2 :002 > Object.class
 => Class
2.2.2 :003 > Module.class
 => Class
2.2.2 :004 > Class.class
 => Class 

Thursday 20 August 2015

How To: Create custom layouts for devise:


1, Define layouts in the ApplicationController
2, Define layouts in config (config/environment.rb for rails 2, config/application.rb in rails 3)

Define layouts in the ApplicationController:

class ApplicationController < ActionController::Base
  layout :check_layout

  protected

  def check_layout
    if devise_controller? && resource_name == :user && action_name == "new"
      "layout_for_devise"
    else
      "application"
    end
  end
end

devise_controller? --> Determine weather it's devise controller or not
resource_name ---> Dealing with roles
action_name --> To determine specific action

2, Define in config:

Below code need to write in application.rb:

#to set layout for specific controller
config.to_prepare do
  Devise::SessionsController.layout "layout_for_sessions_controller"
  Devise::RegistrationsController.layout proc { |controller| user_signed_in? ? "application" : "devise" }
end

#to set layout for devise mailer
config.to_prepare do
  Devise::Mailer.layout "email_layout" #email_layout.erb
end

If u want to write these configurations in devise.rb:
# append to end of config/initializers/devise.rb
Rails.application.config.to_prepare do
  Devise::SessionsController.layout "layout_for_sessions_controller"
  Devise::RegistrationsController.layout proc { |controller| user_signed_in? ? "application" : "layout_for_registration_controller" }
end


that's it..

To generate devise views:
rails generate devise:views

To destroy generate devise views:
rails destroy devise:views

if you want to destroy an especific set of views use:
rails destroy devise:views model
instead of model use the name of the model you want to destroy, for example user, or admin whichever your model is.

Monday 3 August 2015

Rails touch method

touch method:

Saves the record with the updated_at/on attributes set to the current time.

Product.last.touch # it will set update_at with current date and time

Product.last.touch(:last_signed_in) # it will set last_signed_in with current date and time

How to skip rails validation



Skip all validations:

validates :name, presence: true

@user.name = ""
@user.save(validate: false)

It saves the record without running any validations.

Skipping individual validations:

Skipping individual validations requires a bit more work. First, we need to create a property on our model called something like skip_name_validation:

attr_accessor :skip_name_validation, :skip_price_validation

Next we will tell Rails to check and see if that property is set to true:

validates :name, presence: true, uniqueness: true, unless: :skip_name_validation
Validates: price, presence: true, numerically: {greater_than: 0 }, unless: :skip_price_validation

Finally we will set the property to true any time we want to skip validations. For example:

def create
   @product = Product.new(product_params)
   @product.skip_name_validation = true
   if @product.save
    redirect_to products_path, notice: "#{@product.name} has been created."
  else
    render 'new'
  end
end

def update
  @product = Product.find(params[:id])
  @product.attributes = product_params
  @product.skip_price_validation = true
  if @product.save
    redirect_to products_path, notice: "The product \"#{@product.name}\" has been updated. "
  else
    render 'edit'
  end
end

Above you will see that for the create method we skip name validation; and for the update method we skip price validation. A complete listing of the model is shown below.

class Product < ActiveRecord::Base
  validates :name, presence: true, uniqueness: true, unless: :skip_name_validation
  validates :price, presence: true, numericality: { greater_than: 0 }, unless: :skip_price_validation

  attr_accessor :skip_name_validation, :skip_price_validation
end
That's it...:-)


Friday 1 May 2015

Usage Of Yield In Template Rendering

Without any arguments, yield will render the template of the current controller/action. So if you're on the cars/show page, it will render views/carts/show.html.erb.
When you pass yield an argument, it lets you define content in your templates that you want to be rendered outside of that template. For example, if your cars/show page has a specific html snippet that you want to render in the footer, you could add the following to your show template and the car_general layout:
<% content_for :footer do %>
  This content will show up in the footer section
<% end %>
layouts/car_general.html.erb
<%= yield :footer %>