Showing posts with label ROR. Show all posts
Showing posts with label ROR. Show all posts

Wednesday, May 26, 2010

Use of dirty objects

Some times we wanted to know what are the previous values for an object.
We can track the unsaved attribute changes in Rails.
These can be used before save only.

The below are the methods you can use.
* changed
* changed?
* changes

Eg:
Before Assigning:
user = User.find(1)
user.first_name # => "Naga"
user.last_name # => "Harish"
user.changed? # => false
user.changed # => []

After Assigning:
user.first_name = "Turvi"
user.last_name = "Sri"
user.changed? # => true
user.changes # => {"first_name"=>["Naga", "Turvi"], "last_name"=>["Harish", "Sri"]}
user.changed # => ["first_name", "last_name"]

You can also you the dirty suffixes.
DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']

user.first_name_changed? # => true
user.first_name_change # => ["Naga", "Turvi"]
user.first_name_was # => "Naga"
user.first_name_will_change! # => "Turvi"

NOTE: Once you save this record changed? will become false.

So you can have History as one more table or one more column called update_history as column to store all the changes.

Saturday, April 25, 2009

Clone in Ruby

Clone is help ful for the values changed in the object but not the complete object change.

Let me explain with an example.

take an array
arr1 = ["a", "b", "c", "d"]
let me initiliza arr1 to arr2
arr2 = arr1
puts arr2
=> ["a", "b", "c", "d"]


If I change arr1 values i.e.,
arr1[1] = "z"
puts arr1
=> ["a", "z", "c", "d"]

then see arr2
puts arr2
=> ["a", "z", "c", "d"]

#This wil get changed because the whole arr1 is pointed to one block of memory and the same arr2 is also pointing to the same block. You can check this.
arr1.id and arr2.id which will be same.
puts arr1.id
=> 40972250
puts arr2.id
=> 40972250

Suppose if you want arr2 as the previuos arr1 and arr1 should get changed?

Do this:

arr1 = ["a", "b", "c", "d"]
arr2 = arr1.clone
puts arr2
=> ["a", "b", "c", "d"]

arr1[1] = "z"
puts arr1
=> ["a", "z", "c", "d"]

puts arr2
=> ["a", "b", "c", "d"]



But if you change the whole arr1 to some other values then arr2 will not change.
Eg:
arr1 = ["a", "b", "c"]
arr2 = arr1
puts arr2
=> ["a", "b", "c"]

arr1 = ["z", "y", "x"]
puts arr2
=> ["a", "b", "c"]
arr2 will be same as old arr1 because arr1 memory locaton will be different after the new initilaization.

You can check this by arr1.id and arr2.id
In this case clone is not needed.



More about clone (copied from Ruby book(Dave Thomas, The Pragmatic Programmers))---

clone obj.clone -> anObject

Produces a shallow copy of obj---the instance variables of obj are copied, but not the objects they reference. Copies the frozen and tainted state of obj. See also the discussion under Object#dup .

class Klass
attr_accessor :str
end
s1 = Klass.new » #
s1.str = "Hello" » "Hello"
s2 = s1.clone » #
s2.str[1,4] = "i" » "i"
s1.inspect » "#"
s2.inspect » "#"

Saturday, October 25, 2008

Clearing the Email in the logs in Ruby on Rails.

Are your logs printing the complete email when you are sending using Action Mailer in ROR?

By default your Action Mailer will print the log when an email is being sent. So to Avoid this add the following line in envionment.rb where you initialize.

ActionMailer::Base.logger = nil

This should look like below.

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.default_charset = "utf-8"
ActionMailer::Base.logger = nil #this will prevent you by printing in the log.

So this will prevent by printing in all the logs.