rails3 can't iterate from NilClass on model method - ruby-on-rails-3

I'm defining the following Model method:
def live
deb = start_date||= 100.years.ago # if the start date is nil, it's live
fin = end_date||=100.years.from_now # if the end date is nil, it's live
Date.today.between?(deb, fin)
end
if start_date and end_date are filled, the method returns the right value (true or false)
if they're nil, it raises the error "can't iterate from NilClass"

Perhaps a different approach?
def live
deb = self.start_date? ? start_date : 100.years.ago
fin = self.end_date? ? end_date : 100.years.from_now
Date.today.between?(deb.to_date, fin.to_date)
end

Related

Loading ISSUE in rails

I'm facing a problem with Loading a Constant in Rails console (rails console). Here how my structure look like this
- app
- controllers
- models
- earning
- daily_earning.rb
- monthly_earning.rb
- weekly_earning.rb
- yearly_earning.rb
- views
Some more information
I also have a rake which look like this
namespace :past_days do
desc "Past 7 Days Earning"
task :earning => :environment do
puts $:.select { |i| i=~ /models/ }.to_yaml
7.downto(1).each do |i|
start_date = i.days.ago.beginning_of_day
puts "====== Dumping past #{start_date.strftime('%A')} earning ====="
end_date = start_date.end_of_day
Performer.top_daily_earners(start_date,end_date)
puts "====== Dumped #{start_date.strftime('%A')} earning !!! ======="
puts
end
end
end
And the top_daily_earners method look like this If you check this #klass = DailyEarning
def top_daily_earners(start_date=nil,end_date=nil)
unless start_date or end_date
date = 1.day.ago
#start_date,#end_date = date.beginning_of_day,date.end_of_day
end
if start_date and end_date
#start_date,#end_date = start_date,end_date
end
#klass = DailyEarning
#earning_performers = retrieve_earnings
puts "COUNT -----"
puts #earning_performers.count
puts ""
store_earning
end
Question :
Now when I run rake task bundle exec rake past_days:earning (Rake run without any error) all work fine but when I run this
rails console see attach screenshot
I get errors NameError: uninitialized constant DailyEarning and I have manually require the file as can be seen the above screenshot
So the POINT of all the above question is why the error on rails console (NameError: uninitialized constant DailyEarning) and why not the error in
rake task
Attaching DailyEarning Code based on #dtt comment
puts 'DailyEarning'
class DailyEarning
include Mongoid::Document
store_in session: "writeable"
field :performer_id, :type => Integer
field :user_id,:type => Integer
field :stage_name,:type => String
field :full_name,:type => String
field :start_date,:type => DateTime
field :end_date,:type => DateTime
field :amount,:type => BigDecimal
before_create :other_details
## Please avoid using default scope because it AFAIK it make the date parameter as static
class << self
def default_scoping
where(:start_date.gte => 1.day.ago.beginning_of_day).and(:end_date.lte => 1.day.ago.end_of_day)
end
end
private
def other_details
## Fetch from Mongo Instead of Mysql to avoid the slow sql query
performer_source = PerformerSource.where(performer_id: performer_id).only([:stage_name,:user_id]).first
self.user_id = performer_source.user_id
self.stage_name = self.stage_name
#self.full_name = self.full_name
end
end
My understanding is that to autoload a model in a folder you would need to namespace it:
to autoload the model in app/models/earning/daily_earning.rb
class Earning::DailyEarning
end
it may be that instead you could use:
module Earning
class DailyEarning
end
end

How to know whether a request param is missing and throw exception using Rails 3

When I get a request from client in my controller I do:
def index
if (params[:event] == nil || params[:year] == nil || params[:country] == nil)
raise some_error
end
end
Is there a better way to perform it in rails 3.2?
Thanks.
This does the same thing, and though it's a bit more verbose, it's DRYer because it alleviates the need to directly specify each param key in the conditional:
params_hash = []
keys = [:event, :year, :country]
params.each do |key, value|
if keys.include?(key)
params_hash << value
end
end
if params_hash.include?(nil)
raise some_error
end
try:
keys = [:event, :year, :country]
unless (keys - (params.keys & keys)).blank?
raise some_error
end

refactoring callback inside model

I am pretty new to rails and I am trying to create a callback that will apply user information before a record is saved.
Here is the callback:
def add_resolution_name
if self.res_desc_changed?
self.res_provided_name = current_user.first_name
elsif self.res_desc_changed? && self.res_approved?
self.res_provided_name = current_user.first_name
self.res_approved_name = current_user.first_name
elsif self.res_approved_changed? && self.res_approved?
self.res_approved_name = current_user.first_name
elsif self.res_approved_changed? && !self.res_approved?
self.res_approved_name = nil
end
save
logger.info "pocessed resolution information... #{current_user.first_name}"
end
As you can see it's pretty ugly and I don't have access to the current_user inside the ticket model. Should I put this into a presenter or service? Any tips appreciated.
In rails, there's class called ActiveRecord::Observer which allows you to add some event listeners to your own model e.g. before_save, after_save. Have a look here http://api.rubyonrails.org/classes/ActiveRecord/Observer.html
For example
class UserObserver < ActiveRecord::Observer
def before_save(comment)
# your code for add resolution here
end
end

Rails helper method method not works in PDF if sending as an attachment

Hi i have create a PDF conversion in my rails application using Prawn and it working fine.
Now i am sending that PDf in an email attachment. Now problem is that i can send PDF attachment if i do not use any helper method, but when i use my format_currency method in PDf file it gives error on instance_eval method. here is my code sample:
format currency code:
module ApplicationHelper
def format_currency(amt)
unit = 'INR'
country = current_company.country
if !country.blank? && !country.currency_unicode.blank?
unit = country.currency_unicode.to_s
elsif !country.blank?
unit = country.currency_code.to_s
end
number_to_currency(amt, :unit => unit+" ", :precision=> 2)
end
end
My controller code :
pdf.instance_eval do
#company = current_company
#invoice = invoice
#invoice_line_items = invoice_line_items
#receipt_vouchers = receipt_vouchers
eval(template) #this evaluates the template with your variables
end
the error message i got :
undefined method `format_currency' for #<Prawn::Document:0x7f89601c2b68>
with this code i can send attachment successfuly if i don't use helper method but i need to use that method.
I have fixed this issue in a different manner, i have created a new currency_code method in my company model and called that in my format_currency helper method and it is working for me fine:
Here is what i have done :
def currency_code
unit = 'INR'
if !country.blank? && !country.currency_unicode.blank?
unit = country.currency_unicode.to_s
elsif !country.blank?
unit = country.currency_code.to_s
end
unit
end
and used it in my format_currency helper :
def format_currency(amt)
unit = current_company.currency_code
number_to_currency(amt, :unit => unit+" ", :precision=> 2)
end
and in my controller i have added a variable for currency and used it in my pdf file:
pdf.instance_eval do
#company = current_company
#invoice = invoice
#invoice_line_items = invoice_line_items
#receipt_vouchers = receipt_vouchers
#currency = current_company.currency_code # new added variable for currency
eval(template) #this evaluates the template with your variables
end

record_timestamp = false not working from model

I want to track the last_login DateTime of my user, without changing the updated_at attribute.
So inside my Model attribut I put:
def login!(session)
session[:user_id] = id
User.record_timestamp = false
self.touch(:last_login_at)
User.record_timestamp = true
end
also tried, which is the same:
def login!(session)
session[:user_id] = id
self.last_login_at = Time.now
User.record_timestamps = false
self.save(:validate => false)
User.record_timestamps = true
end
But update_at column still is updated after each login.
It seems that User.record_timestamps = false doesn't have any effect when being called from the model directly. (I use to call this method from controller or rake tasks without any problem)
please don't tell me to use update_attribute :last_login_at, Time.now which in Rails 3.1 doesnt set the updated_at column: I'm using rails 3.0.9!
Any idea?
It's really more DRY for me to do this update from the model and not from any controller...
--------------------
[edit] Hummmmmm seems like a bug in rails: I have a nested Class SubUser < User.
When I replace User.record_timestamps = false by self.class.record_timestamps = false then it's working. It's quite strange because:
1) I'm calling #user.login! with a real class User (User.first.login!)
2) even if I were calling SubUser.first.login! the command User.record_timestamps should affect too SubUser class, right?
This is the way I did this before, please give a shot.
def login!(session)
session[:user_id] = id
class << self
def record_timestamps; false; end
end
self.last_login_at = Time.now
self.save(:validate => false)
class << self
remove_method :record_timestamps
end
end
Let me know if it helps you anyway.
I would try using update_attribute because it doesn't do validations so maybe it doesn't update the timestamps either. I'm not sure if it will work:
def login!(session)
update_attribute :last_login_at, Time.now
end