Displaying timestamps for boolean values in Rails 4

时间:2015-07-28 16:56:24

标签: ruby-on-rails activerecord

So I am writing a feature in my Rails app that tracks packages. The way I currently have it set up, each package has many locations (let's say: location 1, location 2, location 3...) which are all initially false. When a package has passed through a certain location, the managers are supposed to mark that as true until it reached the final location. But in the show page for a package I want to show not only these true/false values, but also the exact time when a package passed through each individual location (when it goes from false to true). Any ideas how I might implement/display that?

2 个答案:

答案 0 :(得分:0)

Try associations instead of field.

class Package < ActiveRecord::Base
  has_many :locations
end

class Location < ActiveRecord::Base
  belongs_to :package
end

Then, give your Location the boolean attribute present and the string attribute name. When a package arrives at location 1, create a new location and set that location to name: "location", present: true. Flip the value when the package arrives at location2. Use location.created_at as a time stamp, or do the following:

class Location < ActiveRecord::Base
  belongs_to :package
  after_create :mark_time
  after_save :mark_other_location_false

  def mark_time
    self.time_stamp = Time.now
  end

  def mark_other_location_false
    locations_list = self.package.locations
    other_locations = locations_list - self
    other_locations.map{ |l| l.present = false }
  end
end

This will set your timestamp and mark other locations false.

答案 1 :(得分:0)

Create a marked_at accessor on your class (or create a migration to add the marked_at field to the database):

class Package
  attr_accessor :marked_at

  def marked?
    self.marked_at.present?
  end
end

When a package is marked you can just set package.marked_at = Time.now and use package.marked? to check if it has been marked.

You can also add

def mark!
  self.marked_at = Time.now
end

to your class to mark it with package.mark! from outside. You can also do some logic in the mark! method, like passing in a location and checking if the location is the one where you want to mark your package:

def mark!(location)
  # check if we're at the correct location
  self.marked_at = Time.now if location = self.correct_location
end