pluginaweek / state_machine

Adds support for creating state machines for attributes on any Ruby class
http://www.pluginaweek.org
MIT License
3.74k stars 507 forks source link

Build new object through an association doesn't trigger the state_machine's initial lambda #314

Open Martin91 opened 10 years ago

Martin91 commented 10 years ago

Hey guys, I am using the latest version of state_machine. Today I found a problem that my state_machine doesn't trigger the state_machine's :initial lambda codes if I build objects through an association, but does if I use Order.new.

There are two models, Creator and Order, in my application, and there is a has_many association from a creator to many orders. The below shows the definition of my state_machine for Order:

state_machine :initial => lambda {|order| order.creator_id ? :pending : :unaudited}  do
  state :unaudited, :pending, :open, :finished, :archived

  # other things

The result of building order by the new class method:

[1] pry(main)> order = Order.new :creator_id => 1
=> #<Order id: nil, creator_id: 1, ......, state: "pending">
[2] pry(main)> order.state
=> "pending"

Well, it goes well as what I expect, but, if I build a new order by a creator, it will have something wrong:

[5] pry(main)> creator = Creator.first
=> #<User id: 1, email: "admin@example.com", ...>
[6] pry(main)> order = creator.orders.build
=> #<Order id: nil, creator_id: 1, ......, state: "unaudited>
[7] pry(main)> order.state
=> "unaudited"

See? Both built orders have creator_id, but have opposite state.

Then I add breakpoint to the lambda, I found that the lambda will be run if I build objects through new method, and will never be trigger if through an association.

Could you help me? Thanks in advance.

johnnaegle commented 10 years ago

It looks to me like this is no longer working for new in Rails 4.2

Rails 4.2:

StateMachine.new.calculation_state
=> nil

User.find(142).state_machines.build.calculation_state
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 142]]    
=> nil

Rails 4.0

StateMachine.new.calculation_state
=> "stale"

User.find(142).state_machines.build.calculation_state
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 142]]    
=> "stale"

Note that I didn't have the problem with building through an association, but I'm on a fork.

incubus commented 9 years ago

I've the same problem with Rails 4.2. Have you found a fix or a working fork?

Soleone commented 9 years ago

running into this as well, hopefully this can be fixed and the gem maintained again at some point