How to get the data using find_by Or where in rails? - ruby-on-rails

Truck
id: 1,
vehicle_registration_number: "TN38CC6077",
chassis_number: "12345",
created_at: "2016-09-06 05:39:19",
updated_at: "2016-09-06 05:39:19",
company_truck_type_id: 1,
location_id: 492,
available_date: ["2016-09-10",
"2016-09-20"],
booked_status: "Available",
active: true,
manager_id: 3,
loading_supervisor_id: 3,
transport_supervisor_id: 3,
user_id: 3,
status: "just_in",
price: #<BigDecimal:afae0204,'0.109E5',9(18)>,
source_id: 492,
destination_id: 3,
notes: ["HelloWorld"]
This is my data in a table. From Here I have use available_date to find a current data,but it can't working. How can I get based on current date?
#truck[0].where(available_date:["2016-09-10"]["2016-09-20"])
It's not working. I want to check if the current date is between the available_date or not?

you can do something like below:
Truck.where(available_date: (Time.now.midnight - 1.day)..Time.now.midnight)
Hope that helps you.

Try this code snippets ;
def current_date_is_available?(available_date)
current_date = Date.parse(Time.now.to_s)
Date.parse(available_date.first) < current_date && current_date < Date.parse(available_date.second)
end
in controller ;
if current_date_is_available?(#truck[0].available_date)
# do whatever you want
end

Related

and sometimes I get failed spices because of Time.now, can't understand why

so i have a method in model
class << self
def last_week
start = Time.zone.now.beginning_of_week - 7.days
finish = start + 7.days
where('appointment_at >= ? AND appointment_at < ?', start, finish).order(appointment_at: :desc)
end
end
And I write spec for this method.
RSpec.describe Appointment, type: :model, vcr: { record: :none } do
let!(:time) { Time.now }
let(:appointment_at) { time }
context '.last_week' do
let!(:scoped_appointment) { create(:appointment, appointment_at: time - 2.days) }
let!(:another_appointment) { create(:appointment, appointment_at: time - 16.days) }
it do
travel_to(time) do
expect(Appointment.last_week).to include(scoped_appointment)
expect(Appointment.last_week).not_to include(another_appointment)
end
end
end
end
And sometime i get failed this spec with error.
expected #<ActiveRecord::Relation []> to include #<Appointment id: 18, lead_id: 27, body: nil, appointment_at: "2019-02-25 00:59:47", google_id: nil, ... "pending", user_id: 22, notify: nil, cc_emails: nil, appointment_minutes: nil, status_message: nil>
Diff:
## -1,2 +1,2 ##
-[#<Appointment id: 18, lead_id: 27, body: nil, appointment_at: "2019-02-25 00:59:47", google_id: nil, created_at: "2019-02-27 00:59:47", updated_at: "2019-02-27 00:59:47", timezone: nil, subject: "Meeting with Lead", address: nil, notification: nil, status: "pending", user_id: 22, notify: nil, cc_emails: nil, appointment_minutes: nil, status_message: nil>]
+[]
I can't understand why?
And I have a suggestion that I should tightly set time
in spec_helper.rb
$now = DateTime.parse('2020-01-01 00:00:01 -0500')
will it be right? and why ?
Your test setup is brittle. It will break depending on the day of the week you run your spec.
The scope in your model returns appointments from the previous week, Monday through Sunday (you are calling beginning_of_week and adding 7 days to it)
So if your tests run on a Wednesday, like in the example you provided, the appointment’s appointment_at field will be set to Monday (since you are calculating it as Time.now - 2.days). That means your scope will not cover that appointment.
I suggest you use a specific time in your setup. Given your current setup, using let(:time) { DateTime.parse('2019-02-25 00:00:00') } should work

Rails effective way of looping through daterange

I have ScheduleDay model as;
=> #<ActiveRecord::Relation [#<ScheduleDay id: 1, from: "2017-01-21 00:00:00", to: "2017-01-30 00:00:00", weekday: 100, weekend: 200, weekly: 90, available: true, check_in: "09:00", check_out: "18:00", min_stay: 2, sevendays: false, check_in_day: nil, created_at: "2017-01-14 11:25:18", updated_at: "2017-01-14 11:27:00">, #<ScheduleDay id: 2, from: "2017-02-05 00:00:00", to: "2017-02-15 00:00:00", weekday: 150, weekend: 200, weekly: 140, available: nil, check_in: "09:00", check_out: "18:00", min_stay: 3, sevendays: false, check_in_day: nil, created_at: "2017-01-14 15:53:21", updated_at: "2017-01-14 15:54:43">, #<ScheduleDay id: 3, from: "2017-03-15 00:00:00", to: "2017-06-15 00:00:00", weekday: nil, weekend: nil, weekly: nil, available: false, check_in: nil, check_out: nil, min_stay: 1, sevendays: false, check_in_day: nil, created_at: "2017-01-14 15:56:01", updated_at: "2017-01-14 15:56:57">, #<ScheduleDay id: 4, from: "2017-08-05 00:00:00", to: "2017-09-30 00:00:00", weekday: 500, weekend: 500, weekly: 500, available: true, check_in: "09:00", check_out: "18:00", min_stay: 7, sevendays: true, check_in_day: "Saturday", boat_id: nil, created_at: "2017-01-14 16:01:00", updated_at: "2017-01-14 16:02:10">]>
I have another date range and I would like to loop over my date range in ScheduleDay table and if record is found get some data. If not found then get data as well. I tried couple different way but I m looking for the most efficient way in ruby.
first = Date.parse("05.2.2017")
last = (Date.parse("16.2.2017"))
schedules = ScheduleDay.where(from: Date.today..(last+1.day))
dates = []
(first..last).each do |date|
flag = 0
catch :date_found do
schedules.each do |s|
(s.from.to_date..s.to.to_date).each do |d|
puts date
puts d
if date == d
flag += 1
puts 'found'
throw :date_found
end
end
end
if flag == 0
puts 'date not found'
end
end
end
This is what I have tried so far. But the problem here is I can not access the record if it is not found. If I take;
if flag == 0
puts 'date not found'
end
inside schedules.each... loop then it prints not found for every record in ScheduleDay. I want to loop through all ScheduleDay record and if not found get some data.
EDIT:
I have database records saved by the user. User can customize any date of the year by selecting date range and pricing. I ask user base pricing as well.
So, lets say user entered 15.01.2017 & 21.01.2017 custom price: 100 and base price 200 (base price will be used if date is not found on database date-range).
I would like to return json array of February. So I need;
01.01.2017 -> custom price exists? if not get base price
02.01.2017 -> custom price exists? if not get base price
...
15.01.2017 -> yes! custom price exists get custom price
16.01.2017 -> yes! custom price exists get custom price
17.01.2017 -> yes! custom price exists get custom price
18.01.2017 -> yes! custom price exists get custom price
...
21.01.2017 -> yes! custom price exists get custom price
...
31.01.2017 -> custom price exists? if not get base price
then create json
EDIT2
What if I use;
first = Date.parse("05.2.2017")
last = Date.parse("16.2.2017")
(first..last).each do |date|
schedules.each do |s|
d2 = (s.from.to_date..s.to.to_date)
puts d2 === date
puts d2
puts date
end
end
=== checks date is in the range.

Nil return where it should be exist a value

I'm playing on rails console and did the following steps:
agendamento = Agendamento.last
And got a record that looks like this
#<Agendamento id: 4, sala_id: 2, name: "Delta C", start_at: "2013-10-11 02:00:00", end_at: "2013-10-10 04:00:00", bookingDate: "2013-10-10",
bookingTime: "2000-01-01 23:00:00", bookingDuration: 2, approved: true, usuario_id: nil, created_at: "2013-10-05 02:24:00", updated_at: "2013-
10-05 02:24:00">
when I do agendamento.name I receive:
Delta C
and it works in all values, but not on sala_id, agendamento.sala_id returns
nil
This attribute is acessible in the model, why it is returning nil ?
Environment: Ruby 2 and Rails 4
If sala_id is a foreign key reference, have you tried invoking sala instead? That should give you the related object.

Rails how to calculate multiple sums from one query data

With the following two models, Company and Response, I am making a query of the total responses per company like this:
#allResponses = Company.find(current_user_company_id).responses
this gives me data like this:
[#<Response id: 1, company_id: 1, created_at: "2013-04-24 02:36:54", feedback_score: 10, feedback_explanation: "I really like the way you guys do xyz.", additional_data: "", updated_at: "2013-04-24 02:36:54">, #<Response id: 2, company_id: 1, created_at: "2013-04-25 03:51:07", feedback_score: 5, feedback_explanation: "customer service is spotty.", additional_data: "", updated_at: "2013-04-25 03:51:07">, #<Response id: 3, company_id: 1, created_at: "2013-04-25 03:52:04", feedback_score: 7, feedback_explanation: "You've got potential.", additional_data: "", updated_at: "2013-04-25 03:52:04">, #<Response id: 4, company_id: 1, created_at: "2013-04-25 03:52:18", feedback_score: 9, feedback_explanation: "Almost perfect.", additional_data: "", updated_at: "2013-04-25 03:52:18">]
I want to get the following two variables out of this data:
#sumOfHighScores = some.thing.here #sum of feedback_scores that are greater than 8
#sumOfLowScores = some.thing.here.too #sum of feedback_scores that are less than 7
You can try this,
#sumOfHighScores = #allResponses.select{ |response| response.feedback_score > 8 }.map(&:feedback_score).sum
#sumOfLowScores = #allResponses.select{ |response| response.feedback_score < 7 }.map(&:feedback_score).sum
Try this..
#sumOfHighScores = #allResponses.select{ |response| response.feedback_score > 8 }.sum
#sumOfLowScores = #allResponses.select{ |response| response.feedback_score < 7 }.sum
I will perform the entire calculation in the database.
company = Company.find(current_user_company_id)
totals = company.responses.sum(
:feedback_score,
:group => "CASE WHEN feedback_score < 7 THEN 'low' ELSE 'high' END")
low, high = (totals['low'] || 0), (totals['high'] || 0 )

Rails 3: use contents of an array as variables in a where method

I have three models: Isbn, Sale and Channel.
Aim: to get a list in the isbns show.html.erb view which looks something like this:
Isbn: myisbn
Total sales for myisbn: 100
Myisbn sales for channel 1: 50
Myisbn sales for channel 2: 25
Myisbn sales for channel 3: 25
Here are my models.
Isbn.rb model
has_many :sales
has_many :channels, :through => :sales
Sale.rb model (has attributes sales_channel_id, isbn_id, quantity)
has_many :channels
belongs_to :isbn
Channel.rb model:
belongs_to :sale
I've been working in the isbns controller, in the show method, just to get something to work. I thought I'd refactor later - advice on whether any of this stuff should go in the model would be most welcome.
So far I've got this:
#channelisbn = Sale.where("sales_channel_id =?',1).where("isbn_id=?",3)
#channelsalesisbn = 0
#channelisbn.each {|y| #channelsalesisbn =+ y.quantity}
This successfully gets all the sales where Channel ID is 1 and ISBN id is 3. But it's not much use, as the IDs are hard coded. So I got the Channel IDs into an array:
#channellist = Channel.all
#channel = 0
#channelarray = #channellist.map {|z| #channel = z.id}
which gives me a lovely array of [1,2,3,4]
But I can't figure out how to pass the 1, then the 2, then the 3 and then the 4 into a block which can be used to look up an ISBN's sales which have that sales channel id. This is what I tried (still hardcoding the ISBN id - thought I'd tackle one problem at a time), which returned an empty array:
#channelarray.each do |channel|
#channelisbn = []
#channelisbn = Sale.where("sales_channel_id = ?", channel).where("isbn_id = ?",3)
#channelsalesisbn = 0
#result = []
#result << #channelisbn.each {|a| #channelsalesisbn =+ a.quantity}
end
I was then going to sum the contents of the array.
Any help would be gratefully received. This is my first post, so my zero acceptance rate will change soon!
UPDATE
Just to finish this question off, here's where I've ended up, which is great, and ready for tinkering with: an array, nicely grouped, giving me sales by isbn by channel. Thanks for the group_by tip off!
#in the show action in the isbns controller:
#isbn = Isbn.find(params[:id])
#channelarray = Channel.select(:id).all
#channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", #isbn)}
From the console, line breaks added for clarity:
(sneakily set #isbn = 3 first of all, since in the console you can't pass params from a view, so the #isbn instance defined in the controller is nil in the console)
ruby-1.9.2-p180 :067 > #channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", #isbn)}
=> {[#<Sale id: 1, isbn_id: 3, quantity: 10000, value: 12000, currency: "GBP", total_quantity: nil, created_at: "2011-05-06 12:30:35", updated_at: "2011-05-07 17:43:13", customer: "Waterstone's", retail_price: nil, discount: nil, invoice_date: "2011-05-24">, #<Sale id: 2, isbn_id: 3, quantity: 1000, value: 500, currency: "GBP", total_quantity: nil, created_at: "2011-05-07 09:37:53", updated_at: "2011-05-07 19:14:52", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-02-05">]=>[#<Channel id: 1>],
[#<Sale id: 3, isbn_id: 3, quantity: 500, value: 1500, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:11", updated_at: "2011-05-07 19:15:07", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-12-05">, #<Sale id: 4, isbn_id: 3, quantity: 45, value: 300, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:38", updated_at: "2011-05-07 19:15:36", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-06-05">]=>[#<Channel id: 2>],
[]=>[#<Channel id: 3>],
[]=>[#<Channel id: 4>]}
UPDATE 2
Ha, the hash I generated had the key value pairs the wrong way round. The array containing the sales data was the key - it should have been the value. Rubydocs saved the day:
#salesbychannel = #salesbychannelwrong.invert
The invert method switches the key-value pairs. Sweet.
What you're looking for is passing an array to a ARel#where(), like this:
Sale.where(:sales_channel_id => #channelarray)
This should execute an IN query. If that's not working, you can always pass the array to ActiveRecord#find, like this:
Sale.find(#channelarray)
Hope this helps

Resources