Showing posts with label rails. Show all posts
Showing posts with label rails. Show all posts

Thursday, 18 May 2017

Difference between collect, select, map and each in ruby

To iterate over an array we generally use collect, select, map and each.

All four methods have a similar signature and take a block parameter. The map and collect methods both return an array of values returned by the block. The select method will return the actual values being iterated over if the block evaluates to true

1) Map

Map takes the enumerable object and a block like this [1,2,3].map { |n| n*2 } and evaluates the block for each element and then return a new array with the calculated values.

so the outcome of  [1,2,3].map { |n| n*2 } will be [2,4,6]

If you are try to use map to select any specific values like where n >2 then it will evaluate each element and will output only the result which will be either true or false

so the outcome of  [1,2,3].map { |n| n>2 } will be [false, false, true]

2) Collect

Collect is similar to Map which takes the enumerable object and a block like this [1,2,3].collect { |n| n*2 } and evaluates the block for each element and then return a new array with the calculated values.

so the outcome [1,2,3].collect{ |n| n*2 } of will be [2,4,6]

If you are try to use collect to select any specific values like where n >2 then it will evaluate each element and will output only the result which will be either true or false

so the outcome of  [1,2,3].collect { |n| n>2 } will be [false, false, true]

3) Select

Select evaluates the block with each element for which the block returns true.

so the outcome of  [1,2,3].select { |n| n*2 } will be [1,2,3]

If you are try to use select to get any specific values like where n >2 then it will evaluate each element but returns the original array

so the outcome of  [1,2,3].select{ |n| n>2 } will be [3]

4) Each

Each will evaluate the block with each array and will return the original array not the calculated one.
so the outcome of  [1,2,3].each{ |n| n*2 } will be [1,2,3]

If you are try to use each to select any specific values like where n >2 then it will evaluate each element but returns the original array

so the outcome of  [1,2,3].each { |n| n>2 } will be [1,2,3]

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

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

Monday, 31 August 2015

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 

Monday, 3 August 2015

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 %>

Thursday, 9 April 2015

Mongoid scopes usage

class Person
  include Mongoid::Document
  field :occupation, type: String
  field :age, type: Integer

  scope :rock_n_rolla, -> { where(occupation: "Rockstar") }
  scope :washed_up, where(:age.gt => 30)
  scope :age_or_occupation, ->  {any_of({occupation: "Rockstar"}, {age: 18}) }
  scope :over, ->(limit) { where(:age.gt => limit) }
end

# Find all the rockstars.
Person.rock_n_rolla

# Find all rockstars age greater than 30.
Person.washed_up.rock_n_rolla

# Find all rockstars or other persons have their age as 18 (or operation)
Person.age_or_occupation

# Find a criteria rockstart with 60 as their aget.
Person.rock_n_rolla.over(60)

Friday, 5 September 2014

HOW TO APPLY DIFFERENT LAYOUTS FOR SAME CONTROLLER

class Events::EventsController < AuthenticatedController
layout :user_layout
#for admin
def new
end
def show

end
#for classifieds layout
def classifieds

end
protected
def user_layout
if params[:layout]=="admin"
"admin"
else
"classifieds"
end
end

end

Here i am applaying admin layout to new and show, classfieds to classifieds..

Inorder to apply those two layouts we need to pass layout="admin" as a paramater, in the same way layout="classifieds" for classifieds layout..

Ex: <li><a href="/events/new?layout=admin"><i class="fa fa-angle-double-right"></i>Events</a></li>
end