I am having problem getting net-salary value. I have teacher_payslip model. For calculating net-salary,I have written callback.
In TeacherPayslip.rb
#callbacks
after_create :net_salary
def net_salary
#teacher_id = self.id
#da = (self.basic * self.da)/100
#hra = (self.basic * self.hra)/100
#gs = #da + #hra + self.basic
#pf = (#gs * self.pf)/100
#netsalary = #gs - #pf + self.special_allowance + self.bonus
#raise #netsalary.inspect
#a = TeacherPayslip.find(#teacher_id)
#raise #a.inspect
#a.update_attributes(:net_salary => #netsalary)
end
The net_salary value was updated in TeacherPayslip Model.
In Rails console, I have tried some code
TeacherPayslip.last.net_salary
Shows true value instead of net_salary value
I don't know, Why this query shows true value.. Please Help Me...
It's a naming collision. You're overwriting the method net_salary.
The return value of true is the return value of update_attributes.
To fix this rename your method and the callback to set_net_salary.
user it
TeacherPayslip.last.net_salary
Related
In a rails 4.1 application I need to add an object to an "AssociationRelation"
def index
employee = Employee.where(id_person: params[:id_person]).take
receipts_t = employee.receipts.where(:consent => true) #gives 3 results
receipts_n = employee.receipts.where(:consent => nil).limit(1) #gives 1 result
#I would need to add the null consent query result to the true consent results
#something similar to this and the result is still an association relation
#receipts = receipts_t + receipts_n
end
Is there a simple way to do this?
A way of solving this:
def index
employee_receipts = Employee.find_by(id_person: params[:id_person]).receipts
receipts_t = employee_receipts.where(consent: true)
receipts_n = employee_receipts.where(consent: nil).limit(1)
#receipts = Receipt.where(id: receipts_t.ids + receipts_n.ids)
end
Unfortunately .or() can't be used here because it's only available from Rails v5.0.0.1
you could do this way
receipts_t_ids = employee.receipts.where(:consent => true).pluck(:id)
receipts_n_ids = employee.receipts.where(:consent => nil).limit(1).pluck(:id)
#receipts = Receipt.where(id: receipts_t_ids + receipts_n_ids)
To avoid extra queries and keeping arrays in memory, you can use or
Like this:
def index
employee_receipts = Employee.find_by(id_person: params[:id_person]).receipts
#receipts =
employee_receipts.where(consent: true).or(
employee_receipts.where(consent: nil).limit(1)
)
end
I have a dashboard that allows for filtering of the results by different parameters. I build methods to filter the results by the given criteria. One area where I'm having trouble is if the previous line should null out the active record relation. Should I just put a bunch of if present? stat
def find_website_stats(options = {})
if options[:date_between].present?
start_date = options[:date_between].split(/-/).first.to_date
end_date = options[:date_between].split(/-/).last.to_date + 1
elsif options[:start_date].present?
start_date = options[:start_date].to_date
end_date = options[:end_date].to_date + 1 if options[:end_date].present?
end
contractor_name = options[:search_contractor] if options[:search_contractor].present?
distributor_name = options[:search_distributor] if options[:search_distributor].present?
distributor_ids = options[:with_distributor] if options[:with_distributor].present?
contractor_ids = options[:with_contractor] if options[:with_contractor].present?
with_country = options[:with_country] if options[:with_country].present?
with_state = options[:with_state] if options[:with_state].present?
search_city = options[:search_city] if options[:search_city].present?
web_stats = self.website_stats
if web_stats.present?
web_stats = web_stats.where(contractor_id: [*contractor_ids]) if contractor_ids.present?
if distributor_ids.present?
web_stat_ids = DistributorWebsiteStat.where(distributor_id: [*distributor_ids]).pluck(:website_stat_id)
web_stats = web_stats.where(id: [*web_stat_ids])
end
web_stats = web_stats.where(date_recorded: start_date..end_date) if start_date.present? && end_date.present?
web_stats = web_stats.with_country(with_country) if with_country.present?
web_stats = web_stats.with_state(with_state) if with_state.present?
web_stats = web_stats.search_city(search_city) if search_city.present?
#untested
if contractor_name.present?
searched_contractor_ids = Brand.search_contractor(contractor_name).pluck(:id)
web_stats = web_stats.where(contractor_id: [*searched_contractor_ids])
end
if distributor_name.present?
searched_distributor_ids = Brand.search_distributor(distributor_name).pluck(:id)
web_stat_ids = DistributorWebsiteStat.where(distributor_id: [*searched_distributor_ids])
web_stats = web_stats.where(id: [*web_stat_ids])
end
#end untested
end
web_stats
end
Where I'm specifically having a problem right now is the line that says if web_stat_ids.present?
So at first I grab all the website stats this object is associated with and then look to see if there are any for the given distributor.
If there is none for the given distributor web_stat_ids obviously returns nil
Then when I go to the line web_stats.where(id: [*web_stat_ids]) that's obviously going to return the same thing that I had before, rather than an empty active record relation, which is what I need it to be?
If I make this an empty array the next few statements with "where" won't work because it's an array and not an active record relation.
I know I can wrap this stuff in a bunch of if present? && statements...but I was wondering if there is a better solution to my problem?
In case anyone else is looking for this, found the answer from this SO post: How to return an empty ActiveRecord relation?
Model.none rails 4+
I'd like to ask a little question. It's rather trivial I guess but I might just look for the wrong solutions to my issue so I cant get it working.
I have a model called request.rb which has a method called self.dates
def self.dates
from_date = Request.last.date.to_date
to_date = Request.last.todate.to_date
weekdays = (from_date..to_date).select { |d| (1..5).include?(d.wday)}.count
weekend_days = (from_date..to_date).select { |d| [0, 6].include?(d.wday)}.count
end
I have another model called hotels.rb where I'd like to call the variables weekdays and weekend_days for the price calculation.
def self.best_deal_nm
weekday_nm_tot = (Request.dates.weekdays * pricea.wdpricenm) + (Request.dates.weekdays * pricea.wepricenm)
weekend_nm_tot = (Request.dates.weekend_days * priceb.wdpricenm) + (Request.dates.weekend_days * priceb.wepricenm)
[weekday_nm_tot, weekend_nm_tot].min
end
Unfortunately the code above doesnt work. My question is therefore how can I possibly call these two variables in my hotel model.
Thanks a lot for help
Just return all info in last line into your self.dates method like
def self.dates
from_date = Request.last.date.to_date
to_date = Request.last.todate.to_date
weekdays = (from_date..to_date).select { |d| (1..5).include?(d.wday)}.count
weekend_days = (from_date..to_date).select { |d| [0, 6].include?(d.wday)}.count
{'from_date' => from_date, 'to_date' => to_date, 'weekdays' => weekdays, 'weekend_days' => weekend_days}
end
After call Request.dates from hotels.rb you could access to all variables added to hash.
weekday_nm_tot = (Request.dates['weekdays'] * pricea.wdpricenm) + (Request.dates['weekdays'] * pricea.wepricenm)
I have code in model level to update attribute to TeacherPayslip.
TeacherPayslip.rb (Model)
def net_salary
#teacher_id = self.id
#da = (self.basic * self.da)/100
#hra = (self.basic * self.hra)/100
#gs = #da + #hra + self.basic
#pf = (#gs * self.pf)/100
#netsalary = #gs - #pf + self.special_allowance + self.bonus
#a = TeacherPayslip.find(#teacher_id)
#raise #a.inspect
raise #a.update_attribute('net_salary',#netsalary).inspect
end
Here, when I raise #netsalary shows like 9789. But after updating(#a.update_attribute('net_salary',#netsalary) net_salary shows true value. instead of 9789.
update_attribute return a boolean (true or false). Beside, using update_attribute instead of update_attributes will cause the callbacks to not be fired.
You should use:
#a.update_attributes(net_salary: #netsalary)
#a.net_salary # will hold the new value
I'm trying to make an active record that involves location. I get the longitude from the params, and try to use the Float() method to convert the locationLongitude and locationLatitude from a string to a float, and I get the following error:
undefined method `call' for #<Class:0x007ffead288530>
Here are the params that the method has access to:
{"locationName"=>"Stanford",
"locationLatitude"=>"37.42839679991957",
"locationLongitude"=>"-122.17553785073696"}
And this is the method in my controller that attempts to convert the strings into floats and make the query:
def local
radius = 10;
#sort = "local"
#locationName = params[:locationName]
#locationLongitude = Float(params[:locationLongitude])
#locationLatitude = Float(params[:locationLatitude])
#musings = Musing.(:longitude => (Float(#locationLongitude) - radius)..(Float(#locationLongitude) + radius))
end
Hope you can help. I also tried doing params[:locationName].to_f and that also didn't work.
Thanks, Paul.
I'd say it's better to move the processing from within your local method to the Musing (or other) model.
In your form - try to namespace your parameters such that it'd have a musing as an outer most one.
<input name='musing[locationName' ...>
In the controller
def local
# set some vars
#musings = Musing.search(params[:musing])
end
In the model
def self.search(params)
radius = 10
long = params[:locationLongitude]
lat = params[:locationLatitude]
return self unless long and lat
self.where(:latitude => lat.to_f-radius).where(:long => long.to_f-radius)
end
I can see you resolved the issue - but this might help
Please, change
params[:locationName].to_f
to
params[:locationName].to_s.to_f
The issue was in this line:
#musings = Musing.(:longitude => (Float(#locationLongitude) - radius)..(Float(#locationLongitude) + radius))
I wrote Musing.(...) instead of Musing.where(...)
What a scrub.