Hi all,
What I am trying to do:
- Search for books at a specific school
- Iterate through each book and find all its related subbooks where
the book state is of a specific type
- Return an array of those subbooks for each book
- Since the array will have subarrays of the subbooks, flatten them
into one big array
- then return the subbook with the lowest sequence number
What I did:
subbook = Subbook.get_for_assignment(site, :available_for_assignment)
def self.get_for_assignment(site,book_state)
books = Book.where(:location_id => site, :location_type =>
‘Site’).all
available_books = books.each.map do |book|
book.subbooks.where(:book_state_id =>
BookState[:available_for_assignment].id)
end
raise ApplicationError, "Book out of order" unless
available_books.size > 0
available_book = available_books.flatten.map(&:sequence).min
#available_books.flatten.first (temporary although inaccurate fix)
if available_book.sequence > 100
available_book.book.update_attributes! :book_state_id =>
BookState[:distributed].id
end
available_book
end
The results:
“undefined method sequence for 1:Fixnum”
This line right here:
available_books.flatten.map(&:sequence).min
produces the above error. It’s this part “map(&:sequence).min” that is
causing it. Basically I am flattening the array of subbooks and then
searching the one which has the lowest value for the sequence
attribute, corresponding to a sequence field in the subbooks table.
thanks for response
On 28 June 2011 18:10, John M. [email protected] wrote:
causing it. Basically I am flattening the array of subbooks and then
searching the one which has the lowest value for the sequence
attribute, corresponding to a sequence field in the subbooks table.
The problem is that the “array of subbooks” isn’t an array of
subbooks, it’s an array of something which includes some integers.
Hence, when you iterate it, you get an undefined method for Integer.
I would be inspecting the available_books array in debug (or the
console) and seeing what it really consists of.
BTW, I’d also suggest that the whole “get_for_assignment” method could
be achieved by a scope with the appropriate conditions…
Thanks for response. I checked with logger and it is indeed an array:
logger.info “Is array? #{available_books.flatten.is_a?(Array)}”
#outputs: true
It’s an array of subbook objects:
Subbook:0x10bef7de0#Subbook:0x10bef7ca0#<Subbook:
0x10bef7bb0>#Subbook:0x10bef7ae8#Subbook:0x10bec0ed0#<Subbook:
0x10bec0db8>#Subbook:0x10bec0cc8#Subbook:0x10bec0840#<Subbook:
0x10bea9140>#Subbook:0x10bea8fd8#Subbook:0x10bea8e70#<Subbook:
0x10bea8c90>#Subbook:0x10be8a998#Subbook:0x10be8a678#<Subbook:
0x10be8a268>#Subbook:0x10be86c80#Subbook:0x10be780e0#<Subbook:
0x10be78018>#Subbook:0x10be77f28#Subbook:0x10be77e88#<Subbook:
0x10be69b58>#Subbook:0x10be69ab8#Subbook:0x10be699a0#<Subbook:
0x10be698d8>#Subbook:0x10be63d98#Subbook:0x10be63cf8#<Subbook:
0x10be63b90>#Subbook:0x10be63af0#Subbook:0x10be5d3d0#<Subbook:
0x10be5cd90>#Subbook:0x10be5c4f8#Subbook:0x10be5c3e0#<Subbook:
0x10be53768>#Subbook:0x10be53420#Subbook:0x10be532e0#<Subbook:
0x10be531f0>#Subbook:0x10be46180#Subbook:0x10be45e88#<Subbook:
0x10be45ac8>#Subbook:0x10be45960
Now when I look at above, it appears to reference the class itself,
and since Active Record converts fields to instance methods, the class
itself doesn’t have access to the sequence instance method, only
instances of the class.
Is this the problem and how would I address it?
Thanks for response
hmmm, this returns true as well:
logger.info "is true? #{available_books.flatten.first.respond_to?
(‘sequence’)}"
On Jun 28, 6:10pm, John M. [email protected] wrote:
This line right here:
available_books.flatten.map(&:sequence).min
produces the above error. It’s this part “map(&:sequence).min” that is
causing it. Basically I am flattening the array of subbooks and then
searching the one which has the lowest value for the sequence
attribute, corresponding to a sequence field in the subbooks table.
I suspect the error is actually being raised on the next line where
you do
available_book.sequence > 100
since you’ve set available_book
toavailable_books.flatten.map(&:sequence).min, ie available_book is
the smallest sequence number
Fred
On Jun 29, 12:04am, John M. [email protected] wrote:
actually you are right. my intention was to get the object with the
smallest sequence number, not return the sequence number itself. The
ruby documentation says this: "Returns the object in enum with the
minimum value. " for min. Hence, I thought it would return the object.
It depends what you are iterating over - because you first called
map(&:sequence) the enumerable in question was the array of sequence
numbers. If you want to get back the object with the smallest sequence
value you should drop the call to map and either use the block form of
min or min_by
Fred
Good catch, Fred.
On 29 June 2011 00:04, John M. [email protected] wrote:
actually you are right. my intention was to get the object with the
smallest sequence number
So when you said in your first post: “This line right here …
produces the above error.”, how had you determined it was that line?
The error message would have told you exactly what line was causing
a problem; did you check which line it was, or just assume?
:-/
actually you are right. my intention was to get the object with the
smallest sequence number, not return the sequence number itself. The
ruby documentation says this: "Returns the object in enum with the
minimum value. " for min. Hence, I thought it would return the object.