Reputation: 3337
I have a Rails 3.2.21 app where I'm adding some basic timeclock functionality. I need to build a scope called current_clock_event
that will look for the last record for a user where clock_out: nil
so in essence, the record that will be fetched is the last ClockEvent
record for the user that does not have a value in clock_out
. This is what I want to pass to my controller/view.
class ClockEvent < ActiveRecord::Base
attr_accessible :clock_in, :clock_out, :total_hours, :user_id
scope :current_clock_event, where(clock_out: NIL).last
end
As you can see I wrote a very simple scope to pull a record where the clock_out: NIL
so in theory that should pull the last incomplete record. I think this is working ok but I need to figure out how to access this in the controller and have some sort of conditional to either pull the current_clock_event
or instantiate a new clock event if the last record is completed (both clock_in
and clock_out
are populated)
So I'm stubbing out my controller but am hitting a wall as to how to do this.
class ClockEventsController < ApplicationController
def index
@clock_event = current_user.current_clock_event # need to figure out this part to fetch the record or if the record is complete instantiate a ClockEvent.new for the user.
respond_to do |format|
format.html # index.html.erb
format.js
end
end
end
I wrote code 2 years ago that did all of this but lost the repo by accident so I have nothing to reference and am sort of brain-fogging on how to pull this off.
Any help would be appreciated. If you need more examples or further explanation, please let me know.
Upvotes: 0
Views: 77
Reputation: 3337
I played around with some code and was able to get some refactoring help to make things cleaner. In the User
model I refactored current_clock_event
to just clock_event
and seem to have been able to make the code a bit cleaner, although it's not tested, just stubbed out for now. Let me know what you think.
class ClockEvent
belongs_to :user
scope :incomplete, -> { where(clock_out: nil) }
scope :complete, -> { where.not(clock_out: nil) }
def completed?
clock_in.present? && clock_out.present?
end
end
class User
has_many :clock_events
def clock_event
@clock_event ||= clock_events.incomplete.last || clock_events.new
end
end
class ClockEventsController < ApplicationController
def index
@clock_event = current_user.clock_event
render :index
end
end
Upvotes: 0
Reputation: 17631
You might want to try something like this:
class ClockEvent
belongs_to :user
# you might want to add an order here...
scope :last_clock_event, -> { where("clock_out NULL").last }
def completed?
clock_in.present? && clock_out.present?
end
end
class User
has_many :clock_events
def current_clock_event
ce = clock_events.last_clock_event
ce.completed? ? ClockEvent.new : ce
end
end
class ClockEventsController < ApplicationController
def index
@clock_event = current_user.current_clock_event
render :index
end
end
The completed?
method defined on the ClockEvent
instance allows you to tell if your instance is considered completed or not.
The current_clock_event
method defined at the User
level allows you to define the logic to return either the last clock event record or a new one if completed.
The index
method is pretty straight forward.
Upvotes: 1