That's true: the simplest cases are well covered by the existing features,
but my need are not so simple.

I am writing a few baclground jobs that mass import records in a few tables,
joins them with other data, extract some records, pass the extracted records
to another application (written in php.... araghhhh!), receives the response
from the other application and update part of that records (including state
fields) in a few tables.

Il that jobs, I need to use the state to check complex conditions which
involves the direct execution of SQL queries (using the state strings
directly). which also involves mass changing the state of a quite big number
of records in one go.

Then the application will use vanilla transitions to change the state, but
it's not convenient mass change the state on a per record basis.

I could use the strings without involving constants, it's mostly a matter of
my obsession about good programming style. I suggested it since it's so
simple to add one line in the main code, and because it will make it
consistent with HoboFIelds.

The consideration about wrong constantization of symbols is the same for
HoboFields and it is true, but if you know that your symbols will also
generate constants you can plan good names in advance.

BTW my background jobs need also to generate SHA1 keys to send with emails
and mass update the key_timestamp. That's quite simple to do but what
worries me is the forward compatibility of my jobs with future releases of
hobo.

If for any reason the MyClass::Lifecycle#key method will change the way it
compute the key, the validation key of my application will break updating
hobo to a new release, because it will still use the old way to generate the
key. For that reason I prefer to redefine the methods in the classes that
will use mass import with external generation of the key:

class MyClass::Lifecycle
def key
      require 'digest/sha1'
      timestamp = record.read_attribute(key_timestamp_field)
      self.class.compute_key( record.id, state_name, timestamp) if timestamp
    end

    def self.compute_key record_id, state_name, timestamp
      timestamp = timestamp.getutc
      Digest::SHA1.hexdigest("#{record_id}-#{state_name}-#{timestamp}")
    end
end

Using the MyClass::Lifecycle.compute_key in the background job generation
and overriding the key method will probably make it safer for future
changes.

Again, even if it is prolly a rare case, it could be nice to have the
compute_key method as a separate method in the main code too, so one could
use it in case of external key generation.

Any comment of warning about that matter?



On Tue, Oct 20, 2009 at 11:09 PM, Matt Jones <[email protected]> wrote:

>
>
> On Oct 20, 2009, at 1:28 PM, dd wrote:
>
> > So there is no constant that returns any single state. I solved it
> > by writing a little initializer file:
> >
> >   class Hobo::Lifecycles::DeclarationDSL
> >
> >     def state_with_constants *args, &block
> >       state_without_constants *args, &block
> >       args.extract_options!
> >       args.each { |name| @lifecycle.class_eval "#{name.to_s.upcase}
> > = '#{name}'" }
> >     end
> >
> >     alias_method_chain :state, :constants
> >   end
> >
> > So now I can use any defined state a la HoboFields, to including it
> > in queries without any possible typo
> >
> > MyClass::Lifecycle::ANYSTATE
> >
> > Since the relavant part is just a simple line of code which make it
> > also consistent with HoboFields
> >
> > @lifecycle.class_eval "#{name.to_s.upcase} = '#{name}'"
> >
> > you might consider to include it in your code.
> >
>
> I'm not clear on what the use case for this is. I can't think of many
> cases where you'd actually need to specify a lifecycle state
> explicitly like this; most of them are better covered by features
> already present.
>
> - Finding records in a specific state - use an automatic scope:
> Model.whatever_the_state_name_is.find(:all)
>
> - Figuring out if a particular record is in a state:
> @record.lifecycle.state_name_state?
> [that could probably use some polish]
>
> - Changing a record to a new state: this should really be a
> transition. Barring importing data, if you're whacking state values
> into a lifecycle something's missing from your model.
>
> Not trying to attack anybody, but what's the need for those constants?
>
> Also note that things are allowed in :symbols and state fields that
> don't make valid constants; the code above will die messily when that
> happens. I'll grant that *I* can't think of a good reason to name a
> state :01_foo=bar, or to do silly things with two states named :foo
> and :f0o, but somebody might...
>
> --Matt Jones
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Hobo 
Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/hobousers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to