Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

human_name is ignored in ActiveRecord #260

Open
devdazed opened this issue Jun 9, 2013 · 4 comments
Open

human_name is ignored in ActiveRecord #260

devdazed opened this issue Jun 9, 2013 · 4 comments

Comments

@devdazed
Copy link

devdazed commented Jun 9, 2013

When using ActiveRecord the human_name option is ignored.

@janetruluck
Copy link

Could you give a little more context? Using version 1.2.0 this looks to be working with ActiveRecord. Also, just to make sure, human_name is not actually a method but human_state_name is. Where state in that call is the name of the field you use in your DB/ namespaced state for example given:

class Vehicle
  state_machine :alarm_state, :initial => :active, :namespace => 'alarm' do
    ....
  end
end

your call would be something like:

vehicle = Vehicle.new   
vehicle.human_alarm_state_name

Could this be the issue?

@devdazed
Copy link
Author

No, I tried that, basically here is the issue. In an ActiveRecord Model, I specify the following:

state_machine :send_status, :initial => :not_sent do 
  state :not_sent, :value => 0, :human_name => lambda{self.scheduled_date.nil? ? 'Not Scheduled' : "Scheduled #{self.scheduled_date}"}
  state :sent, :value => 1, :human_name => lambda {"Sent #{self.sent_date}"}
  state :rejected, :value => 2, :human_name => 'Rejected'
end

When I do MyModel.new.human_send_status_name is always comes back as not sent.

It seems to only be affecting ActiveRecord models as if I create a Dummy class model like you did in the example, everything seems to work.

@janetruluck
Copy link

Ah I see, that is pretty different from what I thought you were asking : ). I think the problem may be that the self context is not actually that of your parent instance but of the state_machine object. When testing a sample of your code locally this was the case and I actually received an error trying to use lambda as you state above since the initialization of the State class requires at least the machine and name arguments so I am not sure why it is even sending anything back (for reference).

The problem from looking through the source of that class is that there is no way to get the current instance of the object that you are calling human_send_status_name on unlike a transition which receives the instance your are calling the transition on. The only way around this that I could work out was something like this:

state_machine :send_status, :initial => :not_sent do 
  state :not_sent, :value => 0 do
    def human_send_status_name 
      self.scheduled_date.nil? ? 'Not Scheduled' : "Scheduled #{self.scheduled_date}"
    end
  end

  state :sent, :value => 1 do
    def human_send_status_name 
      "Sent #{self.sent_date}"
    end
  end

  state :rejected, :value => 2, :human_name => 'Rejected'
end

This returns the context of self back to the containing class instance and allows you to call upon it. This is pretty hacky in my opinion but I am not sure if there is a better way, would love to hear what @pluginaweek thinks about this. Hope this helps!

@devdazed
Copy link
Author

Even if I remove the lambda, and use a static string as in the case of Rejected it still doesn't work.
I was able to get the block to work as you have, however, using 4 extra lines for something simple makes it more difficult to read. Especially since this example is shortened from the actual one with about 10 different states.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants