Reputation: 66
I'm trying to get a complicated piece of data from rails.
What I want are all users, the tasks that are associated with them and limited to specific project.
Here's the task schema for reference:
create_table "tasks", force: :cascade do |t|
t.date "start_date"
t.date "end_date"
t.integer "hours"
t.string "priority"
t.integer "project_id"
t.integer "user_id"
t.string "name"
t.string "description"
end
I accomplish parts of this with this call
users = User.includes(:tasks).where('tasks.end_date Between ? AND ?', Date.today.beginning_of_week, Date.today.end_of_week).references(:tasks).where('tasks.start_date Between ? AND ?', Date.today.beginning_of_week, Date.today.end_of_week).references(:tasks).where('tasks.project_id = ?', @project.id).map { |user| user.as_json.merge({tasks: user.tasks.as_json}) }
My problem is that my query is not finding the tasks based on their dates correctly.
I am trying to find all tasks within a week range that either have a start_date or end_date within that week.
Is this possible within one query or do I require more advanced logic?
Upvotes: 2
Views: 3624
Reputation: 66
Here's what ended up working for me, thanks @vijay
User.includes(:tasks).where(tasks: {end_date:Date.today.beginning_of_week..Date.today.end_of_week}).or(User.includes(:tasks).where(tasks: {start_date: Date.today.beginning_of_week..Date.today.end_of_week})).where('tasks.project_id = ?', @project.id).map { |user| user.as_json.merge({tasks: user.tasks.as_json}) }
Upvotes: 0
Reputation: 1683
If you are using Rails 5 you can make user of or
method
User.joins(:tasks).where(tasks: {end_date: Date.today.beginning_of_week..Date.today.end_of_week})
.or(
User.joins(:tasks).where(tasks: {start_date: Date.today.beginning_of_week..Date.today.end_of_week})
)
For sake of brevity, I haven't included project where clause.
Upvotes: 2
Reputation: 435
I haven't tested this but I think what was happening was your where grabbing all of the users with tasks that end_date happens between given times and then querying those models with every user with tasks that start_date happens between given times. Giving you only users whose tasks start_date and end_date happen between the given times.
users = User.includes(:tasks).where('((tasks.end_date BETWEEN ? AND ?) OR (tasks.start_date BETWEEN ? AND ?)) AND tasks.project_id = ?', Date.today.beginning_of_week, Date.today.end_of_week, Date.today.beginning_of_week, Date.today.end_of_week, @project.id).references(:tasks).map { |user| user.as_json.merge({tasks: user.tasks.as_json}) }
Hope it helps. Cheers!
Upvotes: 1