Dalemonaco
Dalemonaco

Reputation: 66

Rails 5 - How to get records with OR condition instead of AND

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

Answers (3)

Dalemonaco
Dalemonaco

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_we‌​ek}).or(User.include‌​s(:tasks).where(task‌​s: {start_date: Date.today.beginning_of_week..Date.today.end_of_week})).wher‌​e('tasks.project_id = ?', @project.id).map { |user| user.as_json.merge({tasks: user.tasks.as_json}) }

Upvotes: 0

Vijay Agrawal
Vijay Agrawal

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

Leo Van Deuren
Leo Van Deuren

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

Related Questions