mhenrixon
mhenrixon

Reputation: 6278

How can I map between strings and attributes automatically?

I have a tiny logical error in my code somewhere and I can't figure out exactly what the problem is. Let's start from the beginning. I have the following extension that my order class uses.

class ActiveRecord::Base   
    def self.has_statuses(*status_names)
      validates :status, 
                :presence => true, 
                :inclusion => { :in => status_names} 

      status_names.each do |status_name|
        scope "all_#{status_name}", where(status: status_name)
      end

      status_names.each do |status_name|
        define_method "#{status_name}?" do
           status == status_name
        end
      end
    end
end    

This works great for the queries and initial setting of "statuses".

require "#{Rails.root}/lib/active_record_extensions"
class Order < ActiveRecord::Base
  has_statuses :created, :in_progress, :approved, :rejected, :shipped
  after_initialize :init

  attr_accessible :store_id, :user_id, :order_reference, :sales_person

  private

    def init
      if  new_record?
        self.status = :created
      end
    end
end    

Now I set a status initially and that works great. No problems at all and I can save my new order as expected. Updating the order on the other hand is not working. I get a message saying:

"Status is not included in the list"

When I check it seems that order.status == 'created' and it's trying to match against :created. I tried setting the has_statuses 'created', 'in_progress' etc but couldn't get some of the other things to work.

Anyway to automatically map between string/attribute?

Upvotes: 0

Views: 243

Answers (1)

Jgubman
Jgubman

Reputation: 4988

from your description, looks like you're comparing a string to a symbol. Probably need to add:

   define_method "#{status_name}=" do
       self.status = status_name.to_sym
    end

or do a #to_s on the status_names

Upvotes: 1

Related Questions