States!


#1

I have, in my local directory a rewrite of the whole ContentState
debacle. The State pattern is definitely the way to go for handling
publication state; dealing with the kind of tangled conditional logic
that we’d have to replace the state objects with gives me the heebie
jeebies.

However, as I’m sure anyone who’s looked at the existing code will
agree, what we have good be a good deal better. The problem is that I
got seduced by the (oh so handy but not quite what I need) existence
of ActiveRecord::Base.composed_of and instead of writing my own class
method to handle marshalling state objects to and from the database, I
used what Rails provided.

When you find yourself overriding ‘new’, it’s probably a good time to
take a good hard think about what you’re trying to achieve.

Anyhoo. A few days ago I was taking part in a discussion about
eliminating conditional code on a blog[1] and I found myself sketching
a rather nicer way of setting up state objects.

So, I’ve implemented it in typo and I must say I’m rather pleased with
it - I expect to be committing it soon, once I’ve given it a more
comprehensive test. Here’s a taster of the new style:

class Article
self.has_state :state,
:valid_states => [:new,
:draft,
:just_published, :published,
:publication_pending,
:just_withdrawn, :withdrawn]
:handles => [:before_save, :after_save,
:withdraw, :published=]

module States
  class New < State
    def before_save
      content.state = :draft
    end

    def published=(boolean)
      return if boolean.nil?
      content.state = boolean ? :just_published : :draft
    end
  end

  class JustPublished < State
    def enter_hook
      class << content; self; end.after_save {|content| 

content.send_pings}
content.state = :published
end
end

  class Published < State
    def enter_hook
      content[:published] = true
      content[:published_at] ||= Time.now
    end

    def withdraw
      content.state = :just_withdrawn
    end
  end

  ...
end
include States

The has_state method deals with all the composed_of type ugliness and
setting up instantiation of state objects and method delgation, and we
can get rid of nasties like ContentState::Factory, which can only be a
good thing.

  1. http://giantrobots.thoughtbot.com/2007/5/1/coding-without-ifs

#2

Le 6 mai 07 à 11:44, Piers C. a écrit :

method to handle marshalling state objects to and from the database, I
it - I expect to be committing it soon, once I’ve given it a more

The has_state method deals with all the composed_of type ugliness and
setting up instantiation of state objects and method delgation, and we
can get rid of nasties like ContentState::Factory, which can only be a
good thing.

  1. http://giantrobots.thoughtbot.com/2007/5/1/coding-without-ifs

Sounds really nice to e. When do you think you’ll have it in the
trunk ? I was planning to release 4.1.1 today, but I can wait until
tuesday for this and the romanian translation file if I can catch it
on time.

Cheers
Frédéric


Frédéric de Villamil
removed_email_address@domain.invalid tel: +33 (0)6 62 19 1337
http://fredericdevillamil.com Typo : http://typosphere.org


#3

Frederic de Villamil removed_email_address@domain.invalid writes:

Sounds really nice to e. When do you think you’ll have it in the
trunk ? I was planning to release 4.1.1 today, but I can wait until
tuesday for this and the romanian translation file if I can catch it
on time.

Release it. I think we should try and stick to regular releases and
not go holding things up because something’s coming down the pike. So
what we the state system isn’t refactored this time, it’ll go into the
next release which isn’t that far off.