Help on find over find

hi all

I have a problem trying to do the following:

MyModel.find(:all).find(:first)

it can look weird or unnecesary but this is the short explanation,
extended one is:

I have a helper method, this receives a collection an return some html,
this helper works fine if that collection is an association (has_many)
of a model but doesn't work if it is a direct find over a model

the error I receive is "LocalJumpError: no block given"

ultra mega extended explanation is:

a model:

class User < ActiveRecord::Base
has_many :requests
end

other model:

class Request < ActiveRecord::Base
def unRequested
  find(:all, conditions => {:state => "unrequested"})
end
end

the helper
module ApplicationHelper
def yearsCalendar (collection)
  years = collection.find(:all, :select => "YEAR(date_created) AS
years")
  years.each do |y|
   html << "<div>#{y}</div>"
  end
end
end

finally at view:
<%= yearsCalendar(User.requests) # WORKS FINE %>

<%= yearsCalendar(Request.unRequested) #WONT WORK , RETURN ERROR:
"LocalJumpError: no block given" %>

any help?, thanks in advance

···

--
Posted via http://www.ruby-forum.com/.

The objects returned by find(:all, ...) and User.requests are
different, and have different APIs. In particular, find(:all) returns
an array, which has a find method defined on it, but it's find method
is very different from the find on an ActiveRecord class.

You might consider changing your yearsCalendar method to look more
like this:

def yearsCalendar (collection)
  years = collection.map {|c| Time.parse(c.date_created).year}
  years.inject("") {|c, i| c << content_tag("div", i)}
end

This avoids the fact that the collections are different classes, and
instead uses what they have in common, ie that they both inherit the
Enumerable module.

Good luck,

e.

···

On Jan 20, 4:05 pm, Mauricio Alcayaga <gusan...@hotmail.com> wrote:

hi all

I have a problem trying to do the following:

MyModel.find(:all).find(:first)

it can look weird or unnecesary but this is the short explanation,
extended one is:

I have a helper method, this receives a collection an return some html,
this helper works fine if that collection is an association (has_many)
of a model but doesn't work if it is a direct find over a model

the error I receive is "LocalJumpError: no block given"

ultra mega extended explanation is:

a model:

class User < ActiveRecord::Base
has_many :requests
end

other model:

class Request < ActiveRecord::Base
def unRequested
find(:all, conditions => {:state => "unrequested"})
end
end

the helper
module ApplicationHelper
def yearsCalendar (collection)
years = collection.find(:all, :select => "YEAR(date_created) AS
years")
years.each do |y|
html << "<div>#{y}</div>"
end
end
end

finally at view:
<%= yearsCalendar(User.requests) # WORKS FINE %>

<%= yearsCalendar(Request.unRequested) #WONT WORK , RETURN ERROR:
"LocalJumpError: no block given" %>

any help?, thanks in advance

--
Posted viahttp://www.ruby-forum.com/.

class User < ActiveRecord::Base
has_many :requests
end

finally at view:
<%= yearsCalendar(User.requests) # WORKS FINE %>

This doesn't make sense, an instance of user should have a method
`requests`, but not the user class itself. I assume this code doesn't
actually work, or it works for some unrelated reason (maybe there is a
method requests defined on ActiveRecord::Base or something)

class Request < ActiveRecord::Base
def unRequested
find(:all, conditions => {:state => "unrequested"})
end
end

<%= yearsCalendar(Request.unRequested) #WONT WORK , RETURN ERROR:
"LocalJumpError: no block given" %>

This also doesn't make sense, for the same reason. unRequested is an
instance method, not a class method. It should be `def self.unRequested`

Anyway, I think Eric probably had it right.
http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-findit
says that all returns an array. There should be a way to return a lazy
finder object that you can then add further queries to, but I don't really
feel like loading Rails up to figure it out (I'd start by looking here
http://guides.rubyonrails.org/active_record_querying.html\). But you don't
want to be creating in memory arrays and then using Ruby's collection
methods, that is not a scalable solution.

Ryan Davis wrote in post #1019657:
>
>> @activityPeriods = coleccion.map{ |x| [x.VARIABLEFIELDNAME.year,
>> x.VARIABLEFIELDNAME.month] }.uniq
>
> I'm not sure I entirely understand your question... but I think you want
> to look at Object.send.

thank you Ryan

anyway, a friend of mine, cristian (zany) zaninovic, gently answer me,
he spoke as: hey bastard, you should use :

paramA = 'year'
paramB = 'month'
dateFieldName = 'name_of_da_field'
@activityPeriods = coleccion.map{ |x|
[eval("x.#{dateFieldName}.#{paramA}"),
eval("x.#{dateFieldName}.#{paramB}")] }.uniq

I didn't try already, but think it will work

--
Posted via http://www.ruby-forum.com/\.

This is a bad plan. First, you should be selecting these objects through
ActiveRecord's query interface. Second, even if you want to use Ruby's
collection methods like #map and #uniq, you should do what Ryan said and use
send:

[x.send("name_of_da_field", "year"), x.send("name_of_da_field", "month")]

This will be faster because you don't have to parse Ruby code, and it will
be safer because there's no possibility of accidentally evaluating arbitrary
code.

···

On Thu, Jan 20, 2011 at 5:05 PM, Mauricio Alcayaga <gusantor@hotmail.com>wrote:
On Thu, Jan 20, 2011 at 5:05 PM, Mauricio Alcayaga <gusantor@hotmail.com> wrote:
On Sat, Sep 3, 2011 at 8:07 AM, Mauricio Alcayaga <gusantor@hotmail.com> wrote:

> On Sep 1, 2011, at 11:31 , Mauricio Alcayaga wrote:

thank you very much Eric, I'll look forward this way

···

--
Posted via http://www.ruby-forum.com/.

hi Eric, hope don't bother you, I followed your suggestion and I have
had success

I ended up with the following funtcion

@activityPeriods = coleccion.map{ |x| [x.date_created.year,
x.date_created.month] }.uniq

as you can see, I'm getting an array of two columns [years, months]
extracted from a collection's (named "coleccion") asking over the field
"date_created"

question: do you know a way, using similar structure, to introduce a
variable as field name to generate the response ? , I mean in te way of:

@activityPeriods = coleccion.map{ |x| [x.VARIABLEFIELDNAME.year,
x.VARIABLEFIELDNAME.month] }.uniq

hope you can help, thanks in advance

Eric Wollesen wrote in post #976398:

···

On Jan 20, 4:05pm, Mauricio Alcayaga <gusan...@hotmail.com> wrote:

this helper works fine if that collection is an association (has_many)
end
module ApplicationHelper
<%= yearsCalendar(User.requests) # WORKS FINE %>

<%= yearsCalendar(Request.unRequested) #WONT WORK , RETURN ERROR:
"LocalJumpError: no block given" %>

any help?, thanks in advance

--
Posted viahttp://www.ruby-forum.com/.

The objects returned by find(:all, ...) and User.requests are
different, and have different APIs. In particular, find(:all) returns
an array, which has a find method defined on it, but it's find method
is very different from the find on an ActiveRecord class.

You might consider changing your yearsCalendar method to look more
like this:

def yearsCalendar (collection)
  years = collection.map {|c| Time.parse(c.date_created).year}
  years.inject("") {|c, i| c << content_tag("div", i)}
end

This avoids the fact that the collections are different classes, and
instead uses what they have in common, ie that they both inherit the
Enumerable module.

Good luck,

e.

--
Posted via http://www.ruby-forum.com/\.

Josh Cheek wrote in post #1019938:

There should be a way to return a lazy
finder object that you can then add further queries to, but I don't
really
feel like loading Rails up to figure it out

In Rails 3 you active Active Relation, where the new query methods
return lazy "relations" which can be chained.
http://m.onkey.org/active-record-query-interface

That is, instead of Klass.find(:all, :conditions=>...) use
Klass.where(:conditions=>)

Also look at named scopes and with_scope:
http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html
http://ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000378

Regards,

Brian.

···

--
Posted via http://www.ruby-forum.com/\.

I'm not sure I entirely understand your question... but I think you want to look at Object.send.

···

On Sep 1, 2011, at 11:31 , Mauricio Alcayaga wrote:

@activityPeriods = coleccion.map{ |x| [x.date_created.year,
x.date_created.month] }.uniq

as you can see, I'm getting an array of two columns [years, months]
extracted from a collection's (named "coleccion") asking over the field
"date_created"

question: do you know a way, using similar structure, to introduce a
variable as field name to generate the response ? , I mean in te way of:

@activityPeriods = coleccion.map{ |x| [x.VARIABLEFIELDNAME.year,
x.VARIABLEFIELDNAME.month] }.uniq

Ryan Davis wrote in post #1019657:

@activityPeriods = coleccion.map{ |x| [x.VARIABLEFIELDNAME.year,
x.VARIABLEFIELDNAME.month] }.uniq

I'm not sure I entirely understand your question... but I think you want
to look at Object.send.

thank you Ryan

anyway, a friend of mine, cristian (zany) zaninovic, gently answer me,
he spoke as: hey bastard, you should use :

paramA = 'year'
paramB = 'month'
dateFieldName = 'name_of_da_field'
@activityPeriods = coleccion.map{ |x|
[eval("x.#{dateFieldName}.#{paramA}"),
eval("x.#{dateFieldName}.#{paramB}")] }.uniq

I didn't try already, but think it will work

···

On Sep 1, 2011, at 11:31 , Mauricio Alcayaga wrote:

--
Posted via http://www.ruby-forum.com/\.