Query with two conditions in Ruby - ruby-on-rails

I have a table Event and I would like to make a unique query that has two conditions. I tried my conditions separately in the console, they work individually. But I do not know how to combine them. The query are as below:
Select event with start:timedate above today (Event that has not happened yet)
Event.where("start > ? " ,Time.now).count
and Also would like to Select event from a specific user_id such as:
Event.where(user_id: "1").count
How could i combine them in a single query please ?
Thank you

Event.where("start > ? " ,Time.now).where(user_id: "1").count
alternatively,
Event.where("user_id = 1 AND start > ?", Time.now).count
You can also use OR statements.

Try scope:
in Event.rb
scope :filter_by_time_user, ->(userId, time) { where('user_id = ? AND start > ?', userId, time) }
And you can call that anywhere like:
Event.filter_by_time_user(1, Time.now).count

Related

Multi-select statement in Rails but trying to prevent duplicate queries for a specific attribute

I am building a Web API for a legacy database and there are some duplicate ids that I need to prevent from being queried.
An example of the duplicates look like this:
FIRST LAST: [
[
"1213.21",
"HHLOG",
"2020-09-18T14:43:00.000-05:00",
"121748.0"
],
[
"1213.21",
"HHLOG",
"2020-09-18T16:30:00.000-05:00",
"121748.0"
]
],
The "121748.0" is actually the pb_id you'll see below in the select statement. These are the type of duplicates I am looking to remove.
Here is my current select statement:
#nova_loads = OpsHeader
.select(:pb_id, :pb_net_rev, :pb_bill_id, :pb_id, :pb_dt_canc)
I have tried a few different things to see if would work:
#nova_loads = OpsHeader
.select((Distinct(pb_id), :pb_net_rev, :pb_bill_id, :pb_id, :pb_dt_canc)
#nova_loads = OpsHeader
.select(:pb_id, :pb_net_rev, :pb_bill_id, :pb_id, :pb_dt_canc).distinct
and a plethora of others. None of them are working and I am little confused as to why.
What do I need to do to have a multi-select statement that can filter off duplicates based off of a certain key value. In this scenario, I will always want the first record of the two. The next record is always the duplicate, so that makes it a little easier... just not for me :D.
EDIT - Here is my full query:
#nova_loads = OpsHeader
.select(:pb_id, :pb_net_rev, :pb_bill_id, :pb_id, :pb_dt_canc)
.where('pb_net_rev > ?', 0.0)
.where(pb_dt_canc: nil)
.joins(ops_stop_rec: :driver_header)
.select(:ops_driver1, :dh_first_name, :dh_last_name, :ops_delivered_time)
.where(:ops_stop_rec => {ops_delivered_time: '2020-09-18 00:00:00' .. '2020-09-18 24:00:00'}).find_each(batch_size: 1000) do |loads, i|
#load_objects.push(loads.dh_first_name + ' ' + loads.dh_last_name => [loads.pb_net_rev, loads.pb_bill_id, loads.ops_delivered_time, loads.pb_id])
end
I've used distinct_on for this. Not fully documented, so might break some time in the future, but here goes:
OpsHeader.select(:pb_id, :pb_net_rev, :pb_bill_id, :pb_id, :pb_dt_canc).tap do |rel|
rel.arel.distinct_on(OpsHeader.arel_table[:pb_id])
end
Also distinct_on currently only works on postgres.

Validations Custom - Compare two variables between new and existing objects (dates) Rails 5

My rails application is a residence application.
I have a model stay which is a third model in a has_many:through assocation between a tenant and a flat. A stay is defined by a checkin_date and a checkout_date. I would like to create a custom validations to prevent the creation of a new stay if there is already a tenant in a flat for a given period...but i never write a custom validation before so i'm super lost...
By logic, i know i need to compare the checkin_date and checkout_date of the "already existing record" and the "supposed new one". So I guess it would look like : (n+1= the new record vs. n= already existing record)
> def duplicate_stay
>
> if Stay.exists?(tenant_id: current_tenant.id, studio_id:
> current_studio.id) &&
> checkin_date(n+1) > checkin_date(n)
> checkout_date(n+1) > checkin_date(n)
> checkin_date(n+1) < checkout_date(n)
> checkout_date(n+1) < checkout_date(n)
> == false
> else
> == true (the model can be created)
end
Can someone help me? I keep looking but I know understand how to do it !
Try using the cover? method. You can use it like this:
today = Date.today
in_one_week = today + 7.days
search_date = today + 3.days
(today..in_one_week).cover? search_date
=> true
This is not tested, but if you added a scope to the Stay class:
scope :overlaps, ->(stay) {
where(
tenant_id: stay.tenant_id,
studio_id: stay.studio_id,
).
where(arel_table[:checkin_date].lt(stay.checkout_date)).
where(arel_table[:checkout_date].gt(stay.checkin_date))
}
... then for an instance of Stay #stay calling Stay.overlaps(#stay).exists? would return true if there was any instance that overlapped with #stay.
Let me know if that doesn't work. It's often helpful to look at the SQL that is executed as part of a validation if you're not sure why something isn't working the way you think it should.
Edit: one tricky thing here is that a stay overlaps with itself, so if #stay was saved successfully (ie. it has an id assigned) you might have a problem with that logic. You can provide different logic depending on whether the record is saved or not, though.
I think that this would do it:
scope :overlaps, ->(stay) {
logic = where(
tenant_id: stay.tenant_id,
studio_id: stay.studio_id,
).
where(arel_table[:checkin_date].lt(stay.checkout_date)).
where(arel_table[:checkout_date].gt(stay.checkin_date))
logic = logic.where.not(id: stay.id) unless stay.new_record?
logic
}

Conditional Dynamic finder in grails

so i require something like the dynamic finder should change as per the condition, let me explain by code what i mean
the below code find all employee by status and lastdateattended
def employee = Employee.findAllByStatusAndLastDateAttended("INA",dateObject)
now i have two fields in Employee LastDateAttended and LastDateSigned , and now i want that if a record does not have LastDateAttended, then it should find by LastDateSigned , otherwise LastDateAttended, so another condition is like
def employee = Employee.findAllByStatusAndLastDateAttended("INA",dateObject)
and i somehow wants to join and use both the query based on a condition , can it be achieved ?, if possible please help
I think criteria query make sense here, something like following
Employee.createCriteria().list{
and{
eq('status','INA')
or {
eq('lastDateAttended',dateObject)
eq('lastDateSigned',dateObject)
}
}
}
Employee.list().findAll { emp->
emp.status == "INA" && ( emp.lastDateAttended!=null?
emp.lastDateAttended.equals(dateObject):emp.lastDateSigned.equals(dateObject)
)
}
Employee.findAllByStatusOrLastDateAttendedOrStatusAndLastDateAttended("INA",dateObject)

How to create a SQL using 'between' in Elixir Ecto

I want to create a SQL using the keywork 'between' in Elixir Ecto.
I know how to create a sql using like
where: like(t.descript, ^some_description)
But when I try to do it in the same way as like
where: between(t.start_date, ^start_date, ^end_date),
I got the "not valid" error msg
** (Ecto.Query.CompileError) `between(t.start_date(), ^start_date, ^end_date)` is not a valid query expression.**
How can I do it the right way?
Thanks in advance!!
I don't think Ecto provides a between clause. You could achieve your task by using
where: t.start_date >= ^start_date,
where: t.start_date <= ^end_date
You can use fragment to do this.
where: fragment("? BETWEEN ? AND ?", t.date, ^start_date, ^end_date)
https://hexdocs.pm/ecto/3.1.4/Ecto.Query.API.html#fragment/1
You can also make your own between macro using the fragment answer #Horvo gave:
#doc """
Checks if the first value is between the second and third value.
"""
defmacro between(value, left, right) do
quote do
fragment("? BETWEEN ? AND ?", unquote(value), unquote(left), unquote(right))
end
end
and use it like you wish you could:
where: between(t.start_date, ^start_date, ^end_date)

LINQ to SQL - Filtering the dataset between two nested collections

I have an MVC 3 project in Visual Studio c#. I have a LINQ to SQL query which works fine and by following an example listed elsewhere on stackoverflow:
Comparing two lists using linq to sql
I have been able to successfully reduce my results where my two nested collections match. This is the bit of code that did the trick (example from the link above):
var anyDesiredSkills = canidateSkills.Any( c => desiredSkills.Select( ds => ds.SkillId ).Contains( c.SkillId ) );
I've adapted this successfully, but now I need to be able to filter records using more than one condition. I was wondering if anyone would be able to adapt the above to show how you could include more than one condition?
To give you some background on what my goal is:
A search page where you can select any number of contacts
Each contact added to the search criteria may/may not have a 'role' assigned. If a role is present this should be factored in to the query.
Results returned based on this dynamic criteria.
Thanks in advance for any and all help :O)
It sounds like you're looking for something like:
var desiredSkillIds = desiredSkills.Select(_=>_.SkillId).ToList();
var matchingContacts =
from contact in Contacts
where contact.Role == null || desiredRoles.Contains(contact.Role)
where contact.Skills.Any(cs=> desiredSkillIds.Contains(cs.SkillId))
select contact;
Or in method-based syntax:
var matchingContacts = Contacts
.Where(contact => contact.Role == null || desiredRoles.Contains(contactRole))
.Where(contact => contact.Skills.Any(cs => desiredSkillIds.Contains(cs.SkillId)));
Here's the final code I used:
servicelist = servicelist.Where(
d => d.ContactSelection.Any(
h => model.ContactFilter.Select(ds => ds.StaffNumber).Contains(h.StaffNumber)
&&
model.ContactFilter.Select(ds => ds.ContactRole).Contains(h.ContactRole) || model.ContactFilter.Select(ds => ds.StaffNumber).Contains(h.StaffNumber) && model.ContactFilter.Select(ds => ds.ContactRole).Contains("0"))
);
Note that the last filter .Contains("0) is the value of '-- select role --' which is an option injected in to the drop down. Hope this helps anyone else!

Resources