I have a 3 models
class Task < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
has_many :clock_ins
accepts_nested_attributes_for :clock_ins, :allow_destroy => true
end
class ClockIn < ActiveRecord::Base
belongs_to :task, :dependent => :destroy
has_one :clock_out
end
class ClockOut < ActiveRecord::Base
belongs_to :clock_in, :dependent => :destroy
end
Currently I can create a ClockIn for each Task.
When I start a new ClockIn, I want to create a ClockOut for whichever Task is currently open.
How do I search my tasks for one with a ClockIn that does not have a ClockOut?
Solution
-
Combine Models
-
Fix destroys
-
Iterate all tasks then update
task.clocks.where(:clock_out => nil).first.update_attribute :clock_out, Time.now
As you have a one-to-one relation between clock_in and clock_out, switching
has_oneandbelongs_toshouldn’t make much difference. What is the data stored in clock_in and clock_out? if is is just a datetime you might want to consider merging the two models and using a single table. If you do not want to change any of the modelingLEFT OUTER JOINis the way to go. So you have three options:Merge the models:
Switch has_one and belongs_to
Go with the outer join
Please note that your
:dependent => :destroydefinitions don’t look very good. Currently if you destroy a clock_out, corresponding clock_in will be destroyed, resulting in corresponding task being destroyed and leaving other clock_ins related with the task orphaned. Also when the task is destroyed, it will result in user being destroyed. This seems to be very odd chain of events. Destroying a clock_out, results in destroying a user, Ouch!You should use
:dependent => :destroylike following: