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

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)

Related

Query with two conditions in Ruby

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

Rails.where Greater/Lesser Than without writing SQL statements

So I have DB query
ageVariable = 36
Actor.where("age > ?", ageVariable)
is that possible to avoid ? syntax?
I'm looking for :key based solution that would look something like this:
Actor.where(age: greater_than(age_variable) or ...where(age: > age_variable)
Edit:
In response to #bounty answer:
Range doesn't solve problem.
Actor.where(:created_at => (1000000.years.ago..2.days.ago) sounds terrible
You can use Arel to get it done without using raw SQL:
Actor.where(Actor.arel_table[:age].gt(36)).all
You can use range condition for this.
ageVariable = (36..1000)
Actor.where(:age => ageVariable)
This will give all actor which are in between 36-1001
ageVariable = 36
Actor.where("age > :target_age", target_age: ageVariable)
I avoided ? and made it look like the latter one ...where(age: > age_variable)...And I'm not even using between but greater than. Did I get closer to what you have in your mind?

Grails: Convert the Hql query to GORM

Kindly, Convert this below hql query to GORM either using criteria or using some API. I am new to grails and I searched enough but I did't get any positive solution for this forgive me if it is simple.
MappingDetail.executeQuery("select map.id from MappingMaster as map where map.id = (select mapdetail.id from MappingDetail as mapdetail where mapdetail.rawdata_template.id=(select rawdata.id from RawDataMasterTemplate as rawdata where rawdata.name like :name))",[name:'%Rick%'])
Why do you have to use criteria here? I think this is the select where you use HQL instead.
def raw = RawDataMasterTemplate.findByNameLike('%Rick%')
def detail = MappingDetail.findByRawdata_template(raw)
def master = MappingMaster.get(detail?.id)
Test this:
MappingMaster.withCriteria {
createAlias 'mappingDetail', 'mp'
createAlias 'mp.rawDtaMasterTemplate', 'rd'
projections {
property 'id'
}
ilike 'rd.name', '%Rick%'
}

European phone formating with rails

With rails, I can format a number into a US phone number with number_to_phone
I'am using using european phone format, which means that I want to group numbers with the following format, n is a variable:
(n*x) xxx-xxx
Some examples
6365555796 => (6365) 555-796
665555796 => (665) 555-796
How to achieve that with the latest rails 3.0.7?
how about so:
def to_phone(num)
groups = num.to_s.scan(/(.*)(\d{3})(\d{3})/).flatten
"(#{groups.shift}) #{groups.shift}-#{groups.shift}"
end
irb(main):053:0> to_phone 318273612
=> "(318) 273-612"
irb(main):054:0> to_phone 3182736122
=> "(3182) 736-122"
irb(main):055:0> to_phone 31827361221
=> "(31827) 361-221"
...
i think you have to write your own method for this there is no built-in method in my knowledge for it and i think you can achieved the desired thing by writing apropriate regular expression for that.
have you tried validate_format_for with: there u can write specific regualr expression for it [see this] http://ruby-forum.com/topic/180192 for writing your own helper for it
check this gem here is what you need http://github.com/floere/phony
A faster approach:
def to_european_phone_format(number)
"(#{number/10**6}) #{number/10**3%10**3}-#{number%10**3}"
end

Ruby gsub function

I'm trying to create a BBcode [code] tag for my rails forum, and I have a problem with the expression:
param_string.gsub!( /\[code\](.*?)\[\/code\]/im, '<pre>\1</pre>' )
How do I get what the regex match returns (the text inbetween the [code][/code] tags), and escape all the html and some other characters in it?
I've tried this:
param_string.gsub!( /\[code\](.*?)\[\/code\]/im, '<pre>' + my_escape_function('\1') + '</pre>' )
but it didn't work. It just passes "\1" as a string to the function.
You should take care of the greedy behavior of the regular expressions. So the correct code looks like this:
html.gsub!(/\[(\S*?)\](.*?)\[\/\1\]/) { |m| escape_method($1, $2) }
The escape_method then looks like this:
def escape_method( type, string )
case type.downcase
when 'code'
"<pre>#{string}</pre>"
when 'bold'
"<b>#{string}</b>"
else
string
end
end
Someone here posted an answer, but they've deleted it.
I've tried their suggestion, and made it work with a small change. Whoever you are, thanks! :)
Here it is
param_string.gsub!( /\[code\](.*?)\[\/code\]/im ) {|s| '<pre>' + my_escape_function(s) + '</pre>' }
You can simply use "<pre>#{$1}</pre>" for your replacement value.

Resources