Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby '.find' method only returning first occurrence

I have models as follows: User has_many goals, Goal has_many tasks, Task has_many day_tasks. I'm trying to write a method which finds all day_tasks that

  1. belong to a certain user
  2. have :target_date == Date.today (target_date is a column in the day_tasks table).

I want to put the results into the @day_tasks array.

my code:

@user = current_user
@day_tasks = DayTask.find { |x| x.task.goal.user == @user && x.target_date == Date.today }

This code only returns the first record that matches these criteria. I've also tried using the DayTasks.where method with the same code in the braces, but I just a "Wrong number of arguments ( 0 for 1 )" error. Could someone explain why my method only returns the first occurrence and what exactly the difference is between .find and .where?

like image 774
Grant David Bachman Avatar asked Oct 04 '11 22:10

Grant David Bachman


2 Answers

You wrote this:

@day_tasks = DayTask.find { |x| x.task.goal.user == @user && x.target_date == Date.today }

The find method here is actually falling back to Enumerable's find, which is an alias for detect, which takes a block and will return the first element in that collection that matches the block's conditions or will return nil.

In order to fix this, you're going to need to use ARel's query stuff that's built-in to ActiveRecord.

DayTask.joins(:task => { :goals => :user }).where("users.id = ? AND day_tasks.target_date = ?", @user.id, Date.today)

The joins method here will join the tables that match the association names in your DayTask model and related models. This means you must have a task association on the DayTask model and on that model have a goals association and on the goals model have one for user.

The where will then construct an SQL condition that will query the joins to find all records that belong to a user and have a target_date of today.

like image 62
Ryan Bigg Avatar answered Nov 07 '22 19:11

Ryan Bigg


please check the ActiveRecord Query Interface for Rails 3.x :

http://m.onkey.org/active-record-query-interface

http://guides.rubyonrails.org/active_record_querying.html

you'll probably want find(:all, ...) or where()

like image 25
Tilo Avatar answered Nov 07 '22 19:11

Tilo