in standby for an annoying problem.

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.

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 ) }

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

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

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.

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

>>> 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.

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 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

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

>
>
>
>>
>> >>> 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.
>>
>> 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 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)

In fact I think my previous comment only applies to production mode

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

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?

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.

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

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.

OK, thanks

Colin

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