kind regards,
Christian
I fear I'll confuse you even more, but I'll try my best to shed some
light on the usage of ruote-kit (furthermore abbreviated as rk) and
Ruote in a Rails app.
Christian wrote:
> I was looking into the directory structure to find out how to start
> developing some views and participants, but I'm completely lost.
There's no need to change rk if you want to use it. rk is (something
like) a RESTful wrapper to Ruote itself. If you want to use the REST
interface rk provides, you could (and probably should) use the client
library ruote-kit-client (http://github.com/kennethkalmer/ruote-kit-client).
> I have little experiences with rails so far.
You don't have to use rk if you just need Ruote in your Rails app (and
btw, you don't even need Rails for rk nor Ruote -- rk is a Sinatra app).
You may:
1. use Ruote directly from your own (Rails|Sinatra|whatever) application
(with or without rk to peep into the running workflow processes)
2. use rk-client to access a running rk instance
3. put rk into your Rack app's middleware stack (see rk's Readme)
I'll use the first option here at my place, so Kenneth will have to
provide some more information on the other two, especially the third
one, which sounds pretty nice (less configuration needs on your side).
The second option would be most useful when your app and rk won't run on
the same server, I suppose.
> Are views completly edited by hand or is it possible to generate them
> via something like a scaffolding?
There's no scaffolding at the moment.
> Where do I put my views in?
What do you like to do with the 'views'?
You'll have to start a new (Rails|Sinatra|whatever) application if you
want to use Ruote or rk. Ruote and rk won't bother where you're views
are ;-)
OK, let's assume you choose the first option mentioned above (sorry,
this is not the answer to your original question, but I hope it helps
anyway) and you plan to write a shiny new Rails app. You could re-use my
configuration example here:
Then, you could use
Ruote.engine
anywhere in your app to access the Ruote engine instance.
Ruote.storage_participant
would be the shortcut to the storage participant registered for
workflow_step_.*.
So let's have an example controller action which simply fetches all
workitems from the storage participant:
class WorklistController < ActionController::Base
def index
@workitems = Ruote.storage_participant.all
end
end
and the corresponding view (app/views/worklist/index.html.haml):
.workitems
- @workitems.each do |wi|
%div[wi]
&= wi.fields['foo']
Note that you'll have to run a Ruote worker by calling
$ rake ruote:run_worker
if you don't want your processes to be stalled.
The mentioned gist includes an example for a custom participant
implementation.
For using rk-client see its Readme, it should be enough to get going.
The controller action could then be rewritten to:
def index
client = RuoteKit::Client(RUOTE_KIT_URL)
@workitems = client.workitems
end
Hope this helps, fire away with further questions,
Torsten
On Feb 1, 3:36 am, Torsten Schoenebaum <torsten.schoeneb...@web.de>
wrote:
A little follow up to my lines on using Ruote from within Rails. I
mentionend "put rk into your Rack app's middleware stack" as possibility
for that without giving further details.
Kenneth did some fine work on that and I added a few more lines so that
now I would propagate to use RuoteKit when there's a need for Ruote on
Rails.
If you need a quickstart, have a look at my example Rails app at
http://github.com/tosch/ruote-on-rails
The only files changed are:
* config/environment.rb
* config/initializers/ruote_kit.rb
* lib/tasks/ruote_kit.rake
You get all the power of the changes done in my previously mentioned
gist plus the possibility to peep into running processes by surfing to
/_ruote.
There's just one drawback at the moment: RuoteKit's views and methods
aren't protected in any way, they are accessible to the world if you
don't protect them by yourself in some way.
So let's dig a little deeper: Where to put your own Ruote stuff?
First of all, you should register your participants in the ruote_kit.rb
initializer file (before the RuoteKit.configure_catchall! call). Note
that you should only use non-instanciated participants as the Ruote
engine when running Rails has no access to a worker instance by default
(instanciated participants will only work if a worker is bound to the
engine). That means: Don't use BlockParticipants! Don't use
ParticipantClass.new. Those will most probably not work.
Some words on the catchall participant: The call to
RuoteKit.configure_catchall!
is a shortcut for the following:
RuoteKit.engine.register_participant('.*', Ruote::StorageParticipant)
So you'll get a storage participant for every participant name you may
think of. If you didn't register your own participants beforehand, every
time a participant expression is entered in your processes, a workitem
will be put in the storage participant. You may access all storaged
workitems by calling RuoteKit.storage_participant.all. See
Ruote::StorageParticipant's inline docu for all methods you may or may
not need ;-)
Note that there is no need to run RuoteKit.configure_catchall! ! The
storage participant will be there anyway, but you'll have to register it
by yourself if you want to use it in your process definitions. You could
register a not so greedy (name-wise) variant:
RuoteKit.engine.register_participant 'storage_+*', Ruote::StorageParticipant
In your process definitions, each participant expression refering to
storage_a or storage_b etc would be handled by the storage participant.
Apropos process definitions: Where to put them? You may keep it simple
and put them in the initializer (writing to some global constant for
example). John likes them to be referenced by urls, so you could put
them as files in some subdirectory of public [1]. You can even put the
process definition to the place where you launch processes. In short
words: It's totally up to you.
Now you have your participants registered and your process definitions
(f)lying around somewhere. Where to launch them? The possibilities are
nearly endless. You could call RuoteKit.engine.launch in your
controllers. I would suggest to use one or more methods in your models
for that, combined with callbacks and/or observers. The best way depends
on your models, so YMMV.
For human participant integration, the storage participant is built. It
holds the workitems until they are explicitely replied to the engine
(you can do this via
RuoteKit.storage_participant.reply(workitem)
). There could be a controller wrapping all this up, but for a start,
there always is /_ruote/workitems ...
That's all for now. I hope this helps and am waiting for questions,
Torsten
[1] Note that you have to set the remote_definition_allowed option of
the engine to true to get that going.
I was able to get your initial setup working fine, but then i tried to
install the ruotekit modifications into my other existing rails app
and now i keep getting this sinatra error:
=> Booting Mongrel
=> Rails 2.3.4 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Fri Feb 19 13:06:04 -0500 2010: Read error: #<MissingSourceFile: no
such file to load -- sinatra/respond_to>
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`gem_original_require'
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/dependencies.rb:156:in `require'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/dependencies.rb:521:in `new_constants_in'
...
any ideas?
Thanks,
Dave
BTW ruote-on-rails works fine with your initial set of instructions.
On Feb 9, 10:02 am, Torsten Schoenebaum <torsten.schoeneb...@web.de>
wrote:
> Hi list!
>
> A little follow up to my lines on using Ruote from within Rails. I
> mentionend "put rk into your Rack app's middleware stack" as possibility
> for that without giving further details.
>
> Kenneth did some fine work on that and I added a few more lines so that
> now I would propagate to use RuoteKit when there's a need for Ruote on
> Rails.
>
> If you need a quickstart, have a look at my example Rails app athttp://github.com/tosch/ruote-on-rails
On Feb 19, 1:11 pm, "Dave @ UPENN" <davejun...@gmail.com> wrote:
> Hey Torsten,
>
> I was able to get your initial setup working fine, but then i tried to
> install the ruotekit modifications into my other existing rails app
> and now i keep getting this sinatra error:
>
> => Booting Mongrel
> => Rails 2.3.4 application starting onhttp://0.0.0.0:3000
I am trying now your old configuration and the new ruote-on-rails in
parallel. But i have still some issues.
I already instaled the ruote-kit gem with sudo gem install ruote-kit.
When I try to do some scaffolding I always get the following errors:
/opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/
gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is
deprecated and will be removed on or after August 2010. Use
#requirement
/ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
`configure_catchall!' for RuoteKit:Module (NoMethodError)
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in
`load_without_new_constant_marking'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in `load'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:521:in `new_constants_in'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in `load'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:622:in `load_application_initializers'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:621:in `each'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:621:in `load_application_initializers'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:176:in `process'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:113:in `send'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:113:in `run'
from /ruote-on-rails/config/environment.rb:9
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `gem_original_require'
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `require'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
commands/generate.rb:1
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `gem_original_require'
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `require'
from script/generate:3
I am using ruby enterprise edition on ubuntu 9.10.
I also have some question about the StorageParticipant. Am I right
with the assumption, that all the workitem manipulation should be done
"outside" any ruote participant?
When is the workitem created?
I did some initialization (engine.launch) and get the workitems out of
the participant with storageParticipant.all. They all seem to be
vompletely empty. Shouldn't they have at least a fei or something
alike stored in it?
I hope my questions are not to stupid.
regards,
Christian
Hello Christian,
next time could you please start a new thread ? Thanks in advance. If
you really need to link to a previous conversation, use a link like :
http://groups.google.com/group/openwferu-users/t/2c012627bdb5b1e7
> I am trying now your old configuration and the new ruote-on-rails in
> parallel. But i have still some issues.
> I already instaled the ruote-kit gem with sudo gem install ruote-kit.
>
> When I try to do some scaffolding I always get the following errors:
>
> (...)
>
> /ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
> `configure_catchall!' for RuoteKit:Module (NoMethodError)
Strange, what does your ruote_kit.rb look like ? No changes from
http://github.com/tosch/ruote-on-rails/blob/master/config/initializers/ruote_kit.rb
?
> (...)
>
> I am using ruby enterprise edition on ubuntu 9.10.
> I also have some question about the StorageParticipant. Am I right
> with the assumption, that all the workitem manipulation should be done
> "outside" any ruote participant?
Please define "ruote participant", please define "outside". Well,
could you please rephrase your question ?
> When is the workitem created?
When a process instance is launched, a workitem is created inside of
the engine and travels throughout the instance. When a concurrence is
reached, the workitem gets cloned, when the concurrence is over, the
workitem gets re-united.
When a workitem reaches a participant expression (something like
'participant :ref => "toto"') the engine will dispatch the workitem
(at least a copy of it) to the "real participant". Usually that
implies calling the "consume" method of a participant implementation.
In the case of StorageParticipant, the workitem will appear in the
list of workitems of the participant and you can "update" it or
directly "reply" with it. (update and reply are two instance methods
of StorageParticipant).
> I did some initialization (engine.launch) and get the workitems out of
> the participant with storageParticipant.all. They all seem to be
> vompletely empty. Shouldn't they have at least a fei or something
> alike stored in it?
There should be a fei :
---8<---
p workitem.fei
p workitem.fields
p workitem.participant_name
--->8---
You can set initial fields for the workitem when launching :
---8<---
RuoteKit.engine.launch(
process_definition,
'project' => 'new pasta machine',
'budget_range' => 'low',
'customer_classes' => [ 'small businesses', 'medium businesses' ])
--->8---
The initial workitem in your newly launched process instance will have
those 3 'project', 'budget_range' and 'customer_classes' fields.
It's also OK to set fields later in the process :
http://ruote.rubyforge.org/exp/set.html
http://ruote.rubyforge.org/exp/restore.html (see "set_fields")
> I hope my questions are not to stupid.
Not at all :) I hope the current answers are helpful.
Best regards,
--
John Mettraux - http://jmettraux.wordpress.com
> I am trying now your old configuration and the new ruote-on-rails in
> parallel.
That means in two parallel Rails instances or in one? I wouldn't
recommend the latter...
> But i have still some issues.
> I already instaled the ruote-kit gem with sudo gem install ruote-kit.
Does it appear in the list when you do a
$ gem list
?
> When I try to do some scaffolding I always get the following errors:
>
> /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/
> gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is
> deprecated and will be removed on or after August 2010. Use
> #requirement
> /ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
> `configure_catchall!' for RuoteKit:Module (NoMethodError)
It seems the ruote-kit gem isn't loaded properly. Do you have access to
other methods the module provides (you could try that in the console)?
How does your environment.rb look like?
Where did you get the gem from? Did you build it yourself or is it the
one from gemcutter.org?
> I am using ruby enterprise edition on ubuntu 9.10.
So do I without having troubles.
Note that the configure_catchall! method will vanish most probably in
one of the next rk versions. Instead, there will be a register method in
the configuration. I will update ruote-on-rails to reflect this change.
Yours,
Tor"there are no stupid questions, but stupid answers"sten
First of all, my problem seemed to be that I had the wrong version of
ruote-kit (2.1.4.1) installed. As I looked into the code I realized,
that there was acually no configure_catchall! Now I have built the gem
myself with the sources from github.
Everything seems to run fine now!
concerning the workitems:
Indeed the workitems I have are not empty. I got it now running fine
(classical PEBKAC :-)
> Well, could you please rephrase your question ?
As Torsten wrote, one should use the storage participant (SP), if
human interaction is present. Thus, I want to use 3 SPs in sequence.
Since the SP cannot have any logic in it, I have to put it into e.g. a
controller where I pull the workitem from the SP and after processing
it, pass it back to the SP. Is this the right way to deal with the
SP?
> That means in two parallel Rails instances or in one?
They were running in parallel instances. Since their engine seems to
have the same ID, I now have all the workitems available in both
instances. Hence, I will discard the "old" Version and run route-on-
rails.
John, thanks for your brief explanation on workitems etc.
Torsten, thank you for your hint about where I got the gem from. That
drove me to the solution. I will also take the 'h' back and use it for
something else. :)
Best regards,
Christian
Hello Christian,
yes, it's fine.
Here is something straight out of a ruote[-kit] + rails app I have :
---8<---
def update # a workitem
workitem = get_workitem
fields = Rufus::Json.decode(params[:workitem]['fields'])
workitem.fields.merge!(fields)
if params[:commit] == 'save'
#
# save
RuoteKit.storage_participant.update(workitem)
redirect_to :action => :show
else # if params[:commit] == 'forward'
#
# forward (workitem resume in flow)
RuoteKit.storage_participant.reply(workitem)
redirect_to :action => :index
end
end
protected
def get_workitem
fei = params[:id]
fei = Ruote::FlowExpressionId.from_id(fei.split('!')[-3..-1].join('!'))
# ruote 2.1.8 will fix that, making that line unnecessary
RuoteKit.storage_participant[fei]
end
--->8---
Workitem is retrieved in storage participant. New field values are
merged in, the if the "action" is 'forward', then the #reply method of
the participant is called, else simply the #update method (which will
save the workitem with its new fields).