Issue in date conversion in ruby - ruby

In my #query I am putting the date in MM-DD-YYYY format. e.g., 01-22-2016. Now I want to search the dates from messages table with that date how can I do. I had added the query:
Message.includes(:user)
.select('messages.*, users.name')
.where(
"users.name ilike ? OR messages.to ilike ? OR messages.created_at.srtftime(\"%Y-%m-%d\") = ?",
"%#{#query}%",
"%#{#query}%",
Date.strptime(#query, "%m-%d-%Y")
)
But I am getting the issue for that:
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "%Y-%m-%d" does not exist
I had also added the query as:
Message.includes(:user)
.select('messages.*, users.name')
.where(
"users.name ilike ? OR messages.to ilike ? OR messages.created_at.srtftime("%Y-%m-%d") = ?",
"%#{#query}%",
"%#{#query}%",
Date.strptime(#query, "%m-%d-%Y")
)
But in that the error is coming as: unknown type of %string

From your comment on #Amadan's answer:
If I don't convert my message.created_at then I am getting blank result.
Message.includes(:user)
.select('messages.*, users.name')
.where(
"users.name ilike ? OR messages.to ilike ? OR messages.created_at = ?",
"%#{#query}%",
"%#{#query}%",
Date.strptime(#query, "%m-%d-%Y")
)
This will produce a query with (among others) a condition like this:
messages.created_at = '2016-01-29 00:00:00'
It should be apparent why this won't work.
messages.created_at is a timestamp, and unless the record just happens to have been created at midnight, that equality comparison is going to fail.
What you need to do is compare the date part of messages.created_at to the date from the query. To get the date part of a timestamp in PostgreSQL, you can use either the date() function or the ::date suffix:
Message.includes(:user)
.select('messages.*, users.name')
.where(
"messages.created_at::date = ?",
Date.strptime(#query, "%m-%d-%Y")
)

Hopefully, you don't have dates stored in the database in VARCHAR columns, but DATETIME or equivalent. Don't convert to String, let ActiveRecord handle dates for you: messages.created_at = ?.

Related

Laravel eloquent possible bug?

I want to join two tables and filter on a field in the joined table. I don't think the actual tables matter in this question, but it's a table with dates joined with a table with the event info, so there are more dates possible for 1 event.
I made this eloquent line:
Event_date::whereRaw('startdate >= curdate() OR enddate >= curdate()')->whereHas('Event', function($q){$q->where("approved",true );})->orderBy('startdate', 'asc')->orderBy('enddate', 'asc')->toSql());
the filter doesn't work though. So thats why i added the ->toSql() to the line.
I get the following back:
select * from `event_dates` where startdate >= curdate() OR enddate >= curdate() and exists (select * from `events` where `event_dates`.`event_id` = `events`.`id` and `approved` = ?) order by `startdate` asc, `enddate` asc
You see that the 'where("approved",true )' results in 'where ..... and and approved = ?)' Where does the questionmark come from??? I tried diferent things, like '1', 1, 'True', True, true, 'true'...everything comes back as a questionmark.
Any suggestions??
Thanks!
Erwin
This is expected behaviour. Laravel uses prepared statements. To get parameters that are put into placeholders, you can use
$query->getBindings();
so for example in your case you can use:
$query = Event_date::whereRaw('startdate >= curdate() OR enddate >= curdate()')->whereHas('Event', function($q){$q->where("approved",true );})->orderBy('startdate', 'asc')->orderBy('enddate', 'asc'));
and now
echo $query->toSql();
var_dump($query->getBindings());
to get both query with placeholders and values that will be put in place of placeholders.

Using PostgreSQL, how do I find all records that have the jsonb column filled out?

Let's say I have a jsonb column type called "data" for the table "recipes". I'm trying to find all records that have "data" filled out (i.e. "data" is not null or an empty bracket {}).
I know for hstore columns, using ruby, you can use a query like this to do so:
Recipe.where("data <> ''")
Is there an equivalent query for jsonb?
Updated after reading the question properly:
You can check for columns with NO data like this
SELECT * FROM table WHERE json_column IS NOT NULL
So this would then be
Recipe.where.not('data IS NULL')
And for columns with non-empty hashes like this:
SELECT * FROM table WHERE json_column <> '{}'
This translates to:
Recipe.where('data <> ?', '{}')
# or
Recipe.where("data <> '{}'")
A good way to verify your query is to run them in SQL first (so you avoid AR and its translation of Ruby to SQL). Then you can try and build the query in AR and use to_sql to see what AR makes of your queries.
Recipe.where('data <> ?', '{}').to_sql
#=> "SELECT \"recipies\".* FROM \"recipies\" WHERE (data <> '{}')"
vs.
Recipe.where('data <> ?', {}).to_sql
#=> "SELECT \"recipies\".* FROM \"recipies\" WHERE (data <> NULL)"

Ruby format DateTimeParameter in where query

I want to do a query like this:
bookings = Booking.where(user_id: #current_user.id, start_at: date.to_datetime)
The problem in this case is, that I just get results in bookings which match a timestamp 00:00:00 which is quite logical.
Is there a possibility to format the start_at parameter in the query to date, so that I just compare two dates and not datetimes?
Try convert your datetime field to date via SQL:
bookings = Booking.where(user_id: #current_user.id)
.where("DATE(start_at) = ?", date)
DATE() extracts the date part of a datetime expression.
Note: it does not works in PotsgreSQL
Or:
bookings = Booking.where(user_id: #current_user.id,
created_at: date.beginning_of_day..date.end_of_day)
How about this?
bookings = Booking.where(user_id: #current_user.id, start_at: start_date..end_date)
or
bookings = Booking.where(user_id: #current_user.id)
.where('start_at > ? AND start_at < ?', start_date, end_date)
where start_date and end_date are the two dates you wish to check between.

How do I compare dates using Eloquent in Laravel?

When I run this code,
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=','2015-06-06');
})->first(['id']);
it gives
select `id` from `entries` where (`interna_id` = 1 and `created_at` = 2015-06-06) limit 1
and as you can see, the date is not enclosed in ''. This causes a problem and MySQL will not be able to find the record. For example, if I add the '', like so,
select `id` from `entries` where (`interna_id` = 1 and `created_at` = '2015-06-06') limit 1
The query is able to retrieve the correct record.
Note:The created_at is using Date format, not DateTime
created_at is of type date for laravel. It uses the Carbon package and expects such an object. You would have to do something like:
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=', Carbon::parse('2015-06-06'));
})->first(['id']);
please note you have to include the library on the page using;
use Carbon\Carbon;enter code here
Alternatively you could use DB::raw for the date as well (untested):
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=', \DB::raw('2015-06-06'));
})->first(['id']);

Error in creating query in openbravo through hql

This question might have answer ... But not for openbravo with postgresql database.
I have openbravo 3.0 framework. In my window i have two date fields namely fromdate and todate. The requirement is i have to write a hql where clause to filter the records on the basis of current date.The date field is of timestamp without timezone.
Means fromdate < currentdate
and todate > currentdate .
I went through this link and wrote the hql where clause as
e.id in(select s.id from Tablename as s where s.fromdate < current_Date and s.todate>current_date)
when i open this window i get this error as
Exception when creating query select e from Tablename as e
where ( e.id in(select s.Tablename_ID from Tablename as s where s.fromdate < (current_date) and s.todate < (current_date)
however if i remove the current date conditions as
e.id in(select s.id from Tablename as s).. It is working fine.
Is it because of current_Date function ? .I tried even with now function .. but i get the same error.
!!! Got The Error.
There is a problem in the query i wrote , in the where clause i am selecting the id's which is not correct,hence when i gave the below query it was running correctly.
(Tablename.fromdate < currrent_date and TableName.todate>current_date) There was no problem with the current_date function.
I thought may be it would help some one!!!
Tip: If you want to write hql query correctly in openbravo , pls install the Hql query tool module that is available freely for community edition of openbravo.
Happy Coding

Resources