in standby for an annoying problem.

23 views
Skip to first unread message

Mauro

unread,
Nov 14, 2012, 4:07:26 PM11/14/12
to rubyonrails-talk
I have a model Reservation with reserved_from and reserve_to
attributes of type date.
I want create a scope of all reservations where Date.today is between
reserved_from and reserved_to.
In the model I've done:

def self.today_reservation
find_each do |res|
if (Date.today).between?(res.reserved_from, res.reserved_to)
return
else
puts "false"
end
end
end
scope :today_reservations, today_reservation

but it doesn't work.
If reserved_from is 2012-11-01 and reserved_to is 2012-11-02 and
Date.today is 2012-11-14 the method above method return an
activerecord relation.
Some advice?
Thank you.

Colin Law

unread,
Nov 14, 2012, 4:21:52 PM11/14/12
to rubyonra...@googlegroups.com
That is not how scopes work. You need something like (not tested)
scope :today_reservations, lambda { where("reserved_from > ? and
reserved_to <= ?", Date.today, Date.today ) }

I expect there is a neater way to do it. Make sure your automated
tests check it on the end points of the range.

Colin


> Some advice?
> Thank you.
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Mauro

unread,
Nov 15, 2012, 3:09:46 AM11/15/12
to rubyonra...@googlegroups.com
On 14 November 2012 22:21, Colin Law <cla...@googlemail.com> wrote:
> On 14 November 2012 21:07, Mauro <mrsa...@gmail.com> wrote:
>> I have a model Reservation with reserved_from and reserve_to
>> attributes of type date.
>> I want create a scope of all reservations where Date.today is between
>> reserved_from and reserved_to.
>> In the model I've done:
>>
>> def self.today_reservation
>> find_each do |res|
>> if (Date.today).between?(res.reserved_from, res.reserved_to)
>> return
>> else
>> puts "false"
>> end
>> end
>> end
>> scope :today_reservations, today_reservation
>>
>> but it doesn't work.
>> If reserved_from is 2012-11-01 and reserved_to is 2012-11-02 and
>> Date.today is 2012-11-14 the method above method return an
>> activerecord relation.
>
> That is not how scopes work. You need something like (not tested)
> scope :today_reservations, lambda { where("reserved_from > ? and
> reserved_to <= ?", Date.today, Date.today ) }

Without lamda it's the same thing?
scope :today_reservations, where("reserved_from > ? and
> reserved_to <= ?", Date.today, Date.today ) works the same.

Colin Law

unread,
Nov 15, 2012, 3:51:20 AM11/15/12
to rubyonra...@googlegroups.com
No it doesn't. Well it does today but if you don't restart the server
then it won't work tomorrow. Without the lambda it is determining
Date.today only once when it loads that line of code. You need the
lambda so that it recalculates it every time you run the scope.

Colin

Jim Ruther Nill

unread,
Nov 15, 2012, 4:11:30 AM11/15/12
to rubyonra...@googlegroups.com
Colin is right but you can also use class methods so you dont have to worry about
adding lambdas

def self.today_reservations
  where('reserved_from > :date AND reserved_to <= :date', date: Date.today)
end
 

Colin

>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
-------------------------------------------------------------
visit my blog at http://jimlabs.heroku.com

Colin Law

unread,
Nov 15, 2012, 9:19:08 AM11/15/12
to rubyonra...@googlegroups.com
Does that have any advantage over using a scope? It has the
disadvantage that one could not say things like
Reservation.where(some conditions).today_reservations

In fact I think my previous comment only applies to production mode
since the code would be reloaded for each request in development mode
and so all would appear to work well - until deployment that is. I am
not even sure how to write a test that would fail for the code without
the lambda.

Colin

Jim Ruther Nill

unread,
Nov 15, 2012, 11:06:12 AM11/15/12
to rubyonra...@googlegroups.com
i don't know if it has any advantage but you can definitely do that.  You can
chain class methods as long as the method returns an active record relation

def self.foo
  # build conditions here
  where(conds)
end

def self.order_method
  order(order_here)
end

then you can use these methods like scopes

Reservation.foo.order_method.where(foo)

In fact I think my previous comment only applies to production mode
since the code would be reloaded for each request in development mode
and so all would appear to work well - until deployment that is.  I am
not even sure how to write a test that would fail for the code without
the lambda.

Colin

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Colin Law

unread,
Nov 15, 2012, 11:37:47 AM11/15/12
to rubyonra...@googlegroups.com
On 15 November 2012 16:06, Jim Ruther Nill <jvn...@gmail.com> wrote:
>
>
>
> On Thu, Nov 15, 2012 at 10:19 PM, Colin Law <cla...@googlemail.com> wrote:
>>
>> On 15 November 2012 09:11, Jim Ruther Nill <jvn...@gmail.com> wrote:
>> > ...
>> > Colin is right but you can also use class methods so you dont have to
>> > worry
>> > about
>> > adding lambdas
>> >
>> > def self.today_reservations
>> > where('reserved_from > :date AND reserved_to <= :date', date:
>> > Date.today)
>> > end
>>
>> Does that have any advantage over using a scope? It has the
>> disadvantage that one could not say things like
>> Reservation.where(some conditions).today_reservations
>
>
> i don't know if it has any advantage but you can definitely do that. You
> can
> chain class methods as long as the method returns an active record relation
>
> def self.foo
> # build conditions here
> where(conds)
> end
>
> def self.order_method
> order(order_here)
> end
>
> then you can use these methods like scopes
>
> Reservation.foo.order_method.where(foo)

Experimentation shows me that you are right, that is a bit of rails
magic that I was not aware of. In fact it seems that one can call any
class method on an ActiveRecord relation for the class. Thanks for
the education.

So the question is, is there any significant difference between a
scope with a lambda and a class method performing the same operation?

Colin

Jordon Bedwell

unread,
Nov 15, 2012, 12:06:30 PM11/15/12
to rubyonra...@googlegroups.com
On Thu, Nov 15, 2012 at 10:37 AM, Colin Law <cla...@googlemail.com> wrote:
> Experimentation shows me that you are right, that is a bit of rails
> magic that I was not aware of. In fact it seems that one can call any
> class method on an ActiveRecord relation for the class. Thanks for
> the education.

It's one of my favorite things to do with ActiveRecord, especially
when storing certain types of records in things like Memcached where
security is more of a cocern to me than a database (in that it has no
scoped ACL like our db's) so I always do something like only with a
where or find_by_* especially since arel (or it might be activerecord
itself) is smart enough to build the entire query long before the last
method in the chain.

> So the question is, is there any significant difference between a
> scope with a lambda and a class method performing the same operation?

From my own experience it depends, sometimes it could be a matter of
just reordering your chain in some cases it might not work at all.
One would have to provide scenarios for a question like this because
it's really up in the air with such a broad scope.

Colin Law

unread,
Nov 15, 2012, 12:15:04 PM11/15/12
to rubyonra...@googlegroups.com
I was trying to ask the general question, that if one has a scope and
a class method that perform exactly the same operation (such as the
example in this thread), so

scope :today_reservations, lambda { where("reserved_from > ? and
reserved_to <= ?", Date.today, Date.today ) }

and

self.today_reservations
where("reserved_from > ? and reserved_to <= ?", Date.today, Date.today ) }
end

Is there actually any difference between the two, or is the former
just a way of defining the latter in a railsy sort of way?

Colin

Jordon Bedwell

unread,
Nov 15, 2012, 12:56:10 PM11/15/12
to rubyonra...@googlegroups.com
On Thu, Nov 15, 2012 at 11:15 AM, Colin Law <cla...@googlemail.com> wrote:
> I was trying to ask the general question, that if one has a scope and
> a class method that perform exactly the same operation (such as the
> example in this thread), so
>
> scope :today_reservations, lambda { where("reserved_from > ? and
> reserved_to <= ?", Date.today, Date.today ) }
>
> and
>
> self.today_reservations
> where("reserved_from > ? and reserved_to <= ?", Date.today, Date.today ) }
> end
>
> Is there actually any difference between the two, or is the former
> just a way of defining the latter in a railsy sort of way?

From what I remember briefly while playing (since I have always
preferred the latter) scope is like attr_writer and attr_reader in
that it's all the same in the end one just gives you more control over
the flow, the other does it all for you but in the end, the result is
exactly the same.

Colin Law

unread,
Nov 15, 2012, 1:05:23 PM11/15/12
to rubyonra...@googlegroups.com
OK, thanks

Colin

Frederick Cheung

unread,
Nov 16, 2012, 3:46:26 AM11/16/12
to rubyonra...@googlegroups.com, cla...@googlemail.com
On Thursday, November 15, 2012 5:16:14 PM UTC, Colin Law wrote:

I was trying to ask the general question, that if one has a scope and
a class method that perform exactly the same operation (such as the
example in this thread), so

scope :today_reservations, lambda {   where("reserved_from > ? and
reserved_to <= ?", Date.today,  Date.today ) }

and

self.today_reservations
  where("reserved_from > ? and reserved_to <= ?", Date.today,  Date.today ) }
end

Is there actually any difference between the two, or is the former
just a way of defining the latter in a railsy sort of way?


I believe some consider the existance of scope :blah, ... to be an error - it adds complexity internally and the potential for the super common lack of lambda error without adding any functionality. I can't remember who said it though.

Fred 
Reply all
Reply to author
Forward
0 new messages