Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ActiveRecord helper to manage an integer `status` column using Ruby :symbols.
- # (C) 2009 Marcello Barnaba <vjt@openssl.it> - Released under the terms of the MIT License
- # http://sindro.me/
- #
- # == Usage ==
- #
- # [REQUIRED] Put this file in lib/
- # [OPTIONAL] Fork this gist
- # [OPTIONAL] Pluginize it
- # [OPTIONAL] Write some tests
- # [OPTIONAL] Notify me
- #
- # Items marked [OPTIONAL] are implicitly marked also
- # [APPRECIATED] and will get you a free beer from me ;)
- #
- # model.rb:
- # require 'statuses'
- #
- # class Model < ActiveRecord::Base
- # has_multiple_statuses :public => 1, :private => 2, :whatever => 3
- # end
- #
- # migration.rb:
- # add_column :models, :status, :integer, :default => [your choice]
- #
- # You get:
- # model.public?, model.private? and model.whatever? that return a Boolean
- # model.status returns the status Symbol (ah ah): model.status #=> :public
- # model.status(:db) return the status Integer: model.status(:db) #=> 1
- # model.status= makes you able to set the status via a Symbol or an Integer:
- # model.status = :public or model.status = 1
- #
- # Have fun! :) -vjt
- #
- module MultipleStatuses
- def self.included(target)
- target.extend ClassMethods
- end
- module ClassMethods
- def has_multiple_statuses(statuses_hash)
- write_inheritable_attribute :statuses, statuses_hash
- class_inheritable_reader :statuses
- statuses_hash.each do |name, status|
- # Defines a query method on the model instance, one
- # for each status name (e.g. Song#published?)
- define_method("#{name}?") { self.read_attribute(:status) == status }
- # Defines on the `statuses` object a method for
- # each status name. Each return the status value.
- # So you can do both statuses[:public] and statuses.public
- #
- class<<statuses;self;end.send(:define_method, name) { status }
- end
- include InstanceMethods
- end
- end
- module InstanceMethods
- def status(format = nil)
- status = read_attribute :status
- if format == :db
- status
- else
- statuses.invert[status]
- end
- end
- def status=(value)
- if statuses.has_key? value
- write_attribute :status, statuses[value]
- elsif statuses.values.include? value
- write_attribute :status, value
- else
- raise ActiveRecord::ActiveRecordError, "invalid status #{value.inspect}"
- end
- end
- end
- end
- ActiveRecord::Base.send :include, MultipleStatuses
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement