0

I have a model called Timesheet which has many TimesheetRows. TimesheetRow belongs to a job.

class Timesheet < ActiveRecord::Base
  has_many :timesheet_rows, inverse_of: timesheet
end
class TimesheetRow < ActiveRecord::Base
  belongs_to :timesheet, inverse_of: timesheet_rows
  belongs_to :job
end

While building a timesheet object from logs, I am trying to check if timesheet_row corresponding to a job has been already built or not, as follows.

timesheet = Timesheet.new()

if timesheet.timesheet_rows.exists?(job_id:n)
  #Do something
else 
  timesheet.timesheet_rows.build(job_id:n)
end

I have tried .exists?(condition) , .find(:all, condition) , .find_by_job_id(n) , .where(condition) etc. All query from database, and thus won't be useful here.

I have browsed for hours now, looking for some magic method but couldn't find any. Really, will I just have to loop through all the associations?

A similar question.

Thanks

Community
  • 1
  • 1
Bot
  • 1,001
  • 2
  • 13
  • 32
  • Why not set an `uniqueness validation` on `job_id` in `TimesheetRow` model? It works in your case. – Pavan Jun 13 '14 at 16:33
  • That validation check will happen whiling saving the timesheet right? I just want to build the timesheet not save. – Bot Jun 13 '14 at 16:40

1 Answers1

1

Try using ruby's select method, and then checking if the resulting array is empty.

if timesheet.timesheet_rows.select { |tr| tr.job_id == n }.empty?
  timesheet.timesheet_rows.build(job_id: n)
else 
  # Do something
end

As @Bot suggested in the comments, you can also use the any? rather than select and empty?.

if timesheet.timesheet_rows.any? { |tr| tr.job_id == n }
  # Do something
else 
  timesheet.timesheet_rows.build(job_id: n)
end
Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
  • Thanks JKen. Now I see three options .any?{}, .detect{}.empty?, .select{}.empty? . I like .any?{} though. Can you add that to your answer? – Bot Jun 13 '14 at 20:11
  • No problem, I'm happy to help. And great call with `any?`, I added it to my answer. – Joe Kennedy Jun 13 '14 at 21:23