Home > Back-end >  Rails - retrieve result of method call from controller in a different model
Rails - retrieve result of method call from controller in a different model

Time:09-21

I'm trying to make a call to my json end point to give me back all the Assignments WHERE the volunteer_shift.date is between params[:start] and params[:end]

Is there a way I can do that in the index method of assignments_controller?

I currently have this in the index method of my controller but it is exploding in my face...

assignments_controller.rb

def index
  @assignments = Assignment.where(volunteer_shift.date: params[:start]..params[:end])  <--- HOW To DO this?
end

Here is what my assignments model looks like...

assignment.rb

class Assignment < ApplicationRecord
  belongs_to :volunteer_shift

  def event_date
    self.volunteer_shift.date
  end
...
end

In my Volunteer_shift model I have a "date" method

volunteer_shift.rb

class VolunteerShift < ApplicationRecord
  has_many :assignments
  belongs_to :volunteer_event
...
  def date
    self.volunteer_event.date
  end
end

is there a way I can get back all the Assignments WHERE the volunteer_shift.date (or assignment.event_date) is between params[:start] and params[:end]?

Note: Rails 5

CodePudding user response:

You can't directly use a method as a active record argument since rails basically uses SQL to retrieve those datas, So, you have to deal with attributes

You can use ActiveRecord#joins to join the tables and then use your "where" statement, like;

 Assignment.joins(volunteer_shift: :volunteer_event).where(volunteer_shifts: {volunteer_events: {date: params[:start]..params[:end] }})

Remember; "joins" arguments must be the models names, while "where" arguments must be the table name


If you wish to hide all this code, you can create a scope to do it, like;

assignment.rb

class Assignment < ApplicationRecord
  belongs_to :volunteer_shift

  scope :date_range, lambda { |range|
    joins(volunteer_shift: :volunteer_event)
      .where(volunteer_shifts: { volunteer_events: { date: range } })
  }

  def event_date
    self.volunteer_shift.date
  end
end

and call with;

Assignment.date_range(params[:start]..params[:end])
  • Related