merb 0.3.4 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +206 -197
 - data/Rakefile +12 -21
 - data/bin/merb +1 -1
 - data/examples/skeleton/Rakefile +6 -20
 - data/examples/skeleton/dist/app/mailers/layout/application.erb +1 -0
 - data/examples/skeleton/dist/conf/database.yml +23 -0
 - data/examples/skeleton/dist/conf/environments/development.rb +1 -0
 - data/examples/skeleton/dist/conf/environments/production.rb +1 -0
 - data/examples/skeleton/dist/conf/environments/test.rb +1 -0
 - data/examples/skeleton/dist/conf/merb.yml +32 -28
 - data/examples/skeleton/dist/conf/merb_init.rb +16 -13
 - data/examples/skeleton/dist/conf/router.rb +9 -9
 - data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +2 -2
 - data/lib/merb.rb +23 -18
 - data/lib/merb/caching/fragment_cache.rb +3 -7
 - data/lib/merb/caching/store/memcache.rb +20 -0
 - data/lib/merb/core_ext/merb_array.rb +0 -0
 - data/lib/merb/core_ext/merb_class.rb +44 -4
 - data/lib/merb/core_ext/merb_enumerable.rb +43 -1
 - data/lib/merb/core_ext/merb_hash.rb +200 -122
 - data/lib/merb/core_ext/merb_kernel.rb +2 -0
 - data/lib/merb/core_ext/merb_module.rb +41 -0
 - data/lib/merb/core_ext/merb_numeric.rb +57 -5
 - data/lib/merb/core_ext/merb_object.rb +172 -6
 - data/lib/merb/generators/merb_app/merb_app.rb +15 -9
 - data/lib/merb/merb_abstract_controller.rb +193 -0
 - data/lib/merb/merb_constants.rb +26 -1
 - data/lib/merb/merb_controller.rb +143 -234
 - data/lib/merb/merb_dispatcher.rb +28 -20
 - data/lib/merb/merb_drb_server.rb +2 -3
 - data/lib/merb/merb_exceptions.rb +194 -49
 - data/lib/merb/merb_handler.rb +34 -26
 - data/lib/merb/merb_mail_controller.rb +200 -0
 - data/lib/merb/merb_mailer.rb +33 -13
 - data/lib/merb/merb_part_controller.rb +42 -0
 - data/lib/merb/merb_plugins.rb +293 -0
 - data/lib/merb/merb_request.rb +6 -4
 - data/lib/merb/merb_router.rb +99 -65
 - data/lib/merb/merb_server.rb +65 -21
 - data/lib/merb/merb_upload_handler.rb +2 -1
 - data/lib/merb/merb_view_context.rb +36 -15
 - data/lib/merb/mixins/basic_authentication_mixin.rb +5 -5
 - data/lib/merb/mixins/controller_mixin.rb +67 -28
 - data/lib/merb/mixins/erubis_capture_mixin.rb +1 -8
 - data/lib/merb/mixins/form_control_mixin.rb +280 -42
 - data/lib/merb/mixins/render_mixin.rb +127 -45
 - data/lib/merb/mixins/responder_mixin.rb +5 -7
 - data/lib/merb/mixins/view_context_mixin.rb +260 -94
 - data/lib/merb/session.rb +23 -0
 - data/lib/merb/session/merb_ar_session.rb +28 -16
 - data/lib/merb/session/merb_mem_cache_session.rb +108 -0
 - data/lib/merb/session/merb_memory_session.rb +65 -20
 - data/lib/merb/template/erubis.rb +22 -13
 - data/lib/merb/template/haml.rb +5 -16
 - data/lib/merb/template/markaby.rb +5 -3
 - data/lib/merb/template/xml_builder.rb +17 -5
 - data/lib/merb/test/merb_fake_request.rb +63 -0
 - data/lib/merb/test/merb_multipart.rb +58 -0
 - data/lib/tasks/db.rake +2 -0
 - data/lib/tasks/merb.rake +20 -8
 - metadata +24 -25
 - data/examples/skeleton.tar +0 -0
 
    
        data/README
    CHANGED
    
    | 
         @@ -1,68 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = Merb
         
     | 
| 
      
 2 
     | 
    
         
            +
            <em>Lightweight MVC Ruby app server. For high performance dynamic pages.</em>
         
     | 
| 
       1 
3 
     | 
    
         | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
            ==== Dependencies
         
     | 
| 
      
 5 
     | 
    
         
            +
            Install these gems first:
         
     | 
| 
       3 
6 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
      
 7 
     | 
    
         
            +
            * mongrel
         
     | 
| 
      
 8 
     | 
    
         
            +
            * erubis
         
     | 
| 
      
 9 
     | 
    
         
            +
            * json
         
     | 
| 
      
 10 
     | 
    
         
            +
            * mime-types
         
     | 
| 
      
 11 
     | 
    
         
            +
            * archive-tar-minitar
         
     | 
| 
      
 12 
     | 
    
         
            +
            * rspec
         
     | 
| 
       5 
13 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
            Then you can build the merb gem from svn trunk like so:
         
     | 
| 
       7 
15 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            mime-types
         
     | 
| 
       13 
     | 
    
         
            -
            archive-tar-minitar
         
     | 
| 
       14 
     | 
    
         
            -
            rspec
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            Install these gems first then you can build the merb gem from svn trunk like so:
         
     | 
| 
       17 
     | 
    
         
            -
            $ sudo gem install mongrel erubis json mime-types archive-tar-minitar rspec --include-dependencies
         
     | 
| 
       18 
     | 
    
         
            -
            $ svn co http://svn.devjavu.com/merb/trunk merb
         
     | 
| 
       19 
     | 
    
         
            -
            $ cd merb
         
     | 
| 
       20 
     | 
    
         
            -
            $ rake install
         
     | 
| 
      
 16 
     | 
    
         
            +
              $ sudo gem install mongrel erubis json mime-types archive-tar-minitar rspec --include-dependencies
         
     | 
| 
      
 17 
     | 
    
         
            +
              $ svn co http://svn.devjavu.com/merb/trunk merb
         
     | 
| 
      
 18 
     | 
    
         
            +
              $ cd merb
         
     | 
| 
      
 19 
     | 
    
         
            +
              $ rake install
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
21 
     | 
    
         
             
            To generate a new merb app after the gem is installed:
         
     | 
| 
       23 
     | 
    
         
            -
            $ merb -g myapp
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
              $ merb -g myapp
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            To run your application, simply type +merb+ in the project directory.
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
            == Features 
         
     | 
| 
       27 
28 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
            built in that parses incoming requests
         
     | 
| 
       30 
     | 
    
         
            -
            including multipart uploads and post as well as  
     | 
| 
      
 29 
     | 
    
         
            +
            === Mongrel handler
         
     | 
| 
      
 30 
     | 
    
         
            +
            Merb has a Mongrel handler built in that parses incoming requests
         
     | 
| 
      
 31 
     | 
    
         
            +
            including multipart uploads and post as well as <tt>?query=strings</tt>. Puts the
         
     | 
| 
       31 
32 
     | 
    
         
             
            params into params and the cookies into cookies when it instantiates your
         
     | 
| 
       32 
33 
     | 
    
         
             
            controller class.
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
            === RouteMatcher and route compiler
         
     | 
| 
       35 
36 
     | 
    
         | 
| 
       36 
37 
     | 
    
         
             
            Reads your route definition and compiles
         
     | 
| 
       37 
38 
     | 
    
         
             
            a method on the fly that will match the request path against each route and do the right thing.
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
            === _NEW_ RESTful Routes
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
            Note the <tt>r.resource :posts</tt> macro. That makes it possible to use a RESTful CRUD style controller for the posts resource
         
     | 
| 
       42 
43 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
            Merb:: 
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
            end
         
     | 
| 
      
 44 
     | 
    
         
            +
            	Merb::Router.prepare do |r|
         
     | 
| 
      
 45 
     | 
    
         
            +
            	  r.resources :posts
         
     | 
| 
      
 46 
     | 
    
         
            +
            	  r.default_routes
         
     | 
| 
      
 47 
     | 
    
         
            +
            	  r.add '/', :controller => 'files', :action => 'index'
         
     | 
| 
      
 48 
     | 
    
         
            +
            	end
         
     | 
| 
       48 
49 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
            The r.default_routes routes adds the standard routes:
         
     | 
| 
      
 50 
     | 
    
         
            +
            The <tt>r.default_routes</tt> routes adds the standard routes:
         
     | 
| 
       50 
51 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
            /controller/action/id.xml
         
     | 
| 
       52 
     | 
    
         
            -
            /controller/action/id
         
     | 
| 
       53 
     | 
    
         
            -
            /controller/action.xml
         
     | 
| 
       54 
     | 
    
         
            -
            /controller/action
         
     | 
| 
       55 
     | 
    
         
            -
            /controller.xml  # index action
         
     | 
| 
       56 
     | 
    
         
            -
            /controller      # index action
         
     | 
| 
      
 52 
     | 
    
         
            +
            	/controller/action/id.xml
         
     | 
| 
      
 53 
     | 
    
         
            +
            	/controller/action/id
         
     | 
| 
      
 54 
     | 
    
         
            +
            	/controller/action.xml
         
     | 
| 
      
 55 
     | 
    
         
            +
            	/controller/action
         
     | 
| 
      
 56 
     | 
    
         
            +
            	/controller.xml  # index action
         
     | 
| 
      
 57 
     | 
    
         
            +
            	/controller      # index action
         
     | 
| 
       57 
58 
     | 
    
         | 
| 
      
 59 
     | 
    
         
            +
            === Controllers
         
     | 
| 
       58 
60 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            *Controllers*
         
     | 
| 
       61 
61 
     | 
    
         
             
            Classes with built in render method and template handling
         
     | 
| 
       62 
62 
     | 
    
         
             
            with instance vars available in the views automatically. Merb also supports 
         
     | 
| 
       63 
63 
     | 
    
         
             
            layouts. It will look for a layout named after your controller class first and
         
     | 
| 
       64 
64 
     | 
    
         
             
            then fall back to application.herb if no layout exists named after your controller.
         
     | 
| 
       65 
     | 
    
         
            -
            You can use render  
     | 
| 
      
 65 
     | 
    
         
            +
            You can use render <tt>:layout => :none</tt>.
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
67 
     | 
    
         
             
            Merb does not automatically render for you in your controller actions, you have
         
     | 
| 
       68 
68 
     | 
    
         
             
            to call render yourself. I consider this a big advantage over the way rails does 
         
     | 
| 
         @@ -70,7 +70,7 @@ it for a few reasons. The main reason is that in rails you can only render once 
     | 
|
| 
       70 
70 
     | 
    
         
             
            per action, so it knows if you haven’t rendered it shoudl auto render. Merb on 
         
     | 
| 
       71 
71 
     | 
    
         
             
            the other hand, returns to the browser whatever the return value of your 
         
     | 
| 
       72 
72 
     | 
    
         
             
            controller’s action method is. This opens up more possibilities imho because
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
      
 73 
     | 
    
         
            +
            now you can return any string from your action and that will be sent down 
         
     | 
| 
       74 
74 
     | 
    
         
             
            the pipe. So Merb’s render method just returns a string and needs to be the 
         
     | 
| 
       75 
75 
     | 
    
         
             
            last thing you call in your action. You can render multiple times and capture 
         
     | 
| 
       76 
76 
     | 
    
         
             
            the results into @ivars and then render a master template with many embeded 
         
     | 
| 
         @@ -81,7 +81,7 @@ return value sent to the client. 
     | 
|
| 
       81 
81 
     | 
    
         | 
| 
       82 
82 
     | 
    
         
             
            That last point has some cool connotations if you think about it. Merb does 
         
     | 
| 
       83 
83 
     | 
    
         
             
            have a mutex lock around the call to your controller’s action anywhere that
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 84 
     | 
    
         
            +
            you can call AR objects. Merb’s lock is way smaller then rails giant lock 
         
     | 
| 
       85 
85 
     | 
    
         
             
            though and allows for many more concurrent requests to be handled by one 
         
     | 
| 
       86 
86 
     | 
    
         
             
            process. By returning a Proc object from your action, you allow merb to 
         
     | 
| 
       87 
87 
     | 
    
         
             
            release the lock and the proc is called in multi threaded way. This allows 
         
     | 
| 
         @@ -90,204 +90,213 @@ release the mutex. It’s basically like handing over the proc to mongrel and 
     | 
|
| 
       90 
90 
     | 
    
         
             
            mongrel handles calling it in a thread safe manner.
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
            class Test < Merb::Controller 
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
            end
         
     | 
| 
      
 93 
     | 
    
         
            +
            	class Test < Merb::Controller 
         
     | 
| 
      
 94 
     | 
    
         
            +
            	  def hello
         
     | 
| 
      
 95 
     | 
    
         
            +
            	    # params, headers and cookies are available here.
         
     | 
| 
      
 96 
     | 
    
         
            +
            	    @name = params[:name]
         
     | 
| 
      
 97 
     | 
    
         
            +
            	    render 
         
     | 
| 
      
 98 
     | 
    
         
            +
            	  end 
         
     | 
| 
      
 99 
     | 
    
         
            +
            	end
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
101 
     | 
    
         
             
            You can also render partials like so:
         
     | 
| 
       102 
     | 
    
         
            -
            <%= partial(:comments) %>
         
     | 
| 
       103 
102 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
      
 103 
     | 
    
         
            +
            	<%= partial(:comments) %>
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
            This assumes a <tt>_comments.rhtml</tt> file in the same view dir as the current 
         
     | 
| 
      
 106 
     | 
    
         
            +
            controller/view.
         
     | 
| 
       106 
107 
     | 
    
         | 
| 
       107 
108 
     | 
    
         
             
            Partials compile the template ands returns a string. So you can also call
         
     | 
| 
       108 
109 
     | 
    
         
             
            them and assign them to a var if you want:
         
     | 
| 
       109 
110 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
            def someaction
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
            end
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
            partial('/shared/foo')
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
            supports multi return values based on the accept header via respond_to
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
            class Posts < Merb::Controller
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
            end
         
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
      
 111 
     | 
    
         
            +
            	def someaction
         
     | 
| 
      
 112 
     | 
    
         
            +
            	  @one = partial(:one)
         
     | 
| 
      
 113 
     | 
    
         
            +
            	  @two = partial(:two)
         
     | 
| 
      
 114 
     | 
    
         
            +
            	end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            Partials can also render views from other controllers by specifying the path:
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            	partial('/shared/foo')
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            Merb also allows for returning JavaScript instead of html for ajax actions
         
     | 
| 
      
 121 
     | 
    
         
            +
            You have to use the render_js instead of normal render:
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            	def ajax_action
         
     | 
| 
      
 124 
     | 
    
         
            +
            	  @posts = Post.find :all
         
     | 
| 
      
 125 
     | 
    
         
            +
            	  render_js
         
     | 
| 
      
 126 
     | 
    
         
            +
            	end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            	# ajax_action.jerb
         
     | 
| 
      
 129 
     | 
    
         
            +
            	$('comments').update('<%=js partial(:posts) %>');
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            	# _posts.herb
         
     | 
| 
      
 132 
     | 
    
         
            +
            	<ul>
         
     | 
| 
      
 133 
     | 
    
         
            +
            	  <% @posts.each do |p| %>
         
     | 
| 
      
 134 
     | 
    
         
            +
            	    <li>
         
     | 
| 
      
 135 
     | 
    
         
            +
            	    <%= p.title %><br />
         
     | 
| 
      
 136 
     | 
    
         
            +
            	    <%= p.body %>
         
     | 
| 
      
 137 
     | 
    
         
            +
            	    </li>
         
     | 
| 
      
 138 
     | 
    
         
            +
            	  <% end %>
         
     | 
| 
      
 139 
     | 
    
         
            +
            	</ul>	
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            The .jerb template is used for this purpose.
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            ==== RESTful Controllers
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            RESTful controllers use a different dispatch system based on the request method verbs. Merb
         
     | 
| 
      
 146 
     | 
    
         
            +
            supports multi return values based on the accept header via +respond_to+.
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            	class Posts < Merb::Controller
         
     | 
| 
      
 149 
     | 
    
         
            +
            	  # GET /posts
         
     | 
| 
      
 150 
     | 
    
         
            +
            	  # GET /posts.xml
         
     | 
| 
      
 151 
     | 
    
         
            +
            	  def index
         
     | 
| 
      
 152 
     | 
    
         
            +
            	    @posts = Post.find :all
         
     | 
| 
      
 153 
     | 
    
         
            +
            	    respond_to {|format|
         
     | 
| 
      
 154 
     | 
    
         
            +
            	      format.html { render }
         
     | 
| 
      
 155 
     | 
    
         
            +
            	      format.js   { render :js => :index }
         
     | 
| 
      
 156 
     | 
    
         
            +
            	      format.xml  { render :xml => @posts.to_xml }
         
     | 
| 
      
 157 
     | 
    
         
            +
            	    }
         
     | 
| 
      
 158 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            	  # GET /posts/1
         
     | 
| 
      
 161 
     | 
    
         
            +
            	  # GET /posts/1.xml
         
     | 
| 
      
 162 
     | 
    
         
            +
            	  def show
         
     | 
| 
      
 163 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            	  # GET /posts/new
         
     | 
| 
      
 166 
     | 
    
         
            +
            	  def new
         
     | 
| 
      
 167 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            	  # GET /posts/1;edit
         
     | 
| 
      
 170 
     | 
    
         
            +
            	  def edit
         
     | 
| 
      
 171 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            	  # POST /posts
         
     | 
| 
      
 174 
     | 
    
         
            +
            	  # POST /posts.xml
         
     | 
| 
      
 175 
     | 
    
         
            +
            	  def create
         
     | 
| 
      
 176 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            	  # PUT /posts/1
         
     | 
| 
      
 179 
     | 
    
         
            +
            	  # PUT /posts/1.xml
         
     | 
| 
      
 180 
     | 
    
         
            +
            	  def update
         
     | 
| 
      
 181 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
            	  # DELETE /posts/1
         
     | 
| 
      
 184 
     | 
    
         
            +
            	  # DELETE /posts/1.xml
         
     | 
| 
      
 185 
     | 
    
         
            +
            	  def destroy
         
     | 
| 
      
 186 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 187 
     | 
    
         
            +
            	end
         
     | 
| 
      
 188 
     | 
    
         
            +
            	
         
     | 
| 
      
 189 
     | 
    
         
            +
            Learn more about this in the controller documentation.
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
            ==== Before and after filters
         
     | 
| 
       190 
192 
     | 
    
         | 
| 
       191 
193 
     | 
    
         
             
            Use the before method in your controllers. before accepts either a symbol, string or a Proc/lambda object. If you give it a symbol it will call a method with the same name as the symbol. If you give it a proc that takes one argument it will call the proc with the current controller as that argument. You can use :only and :exclude as options to your filters to exclude or include actionsfrom certain filters. :only and :exclude take :symbols or [:sym, :sam] array of symbols.
         
     | 
| 
       192 
194 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
            class Foo < Merb::Controller
         
     | 
| 
      
 195 
     | 
    
         
            +
            	class Foo < Merb::Controller
         
     | 
| 
       194 
196 
     | 
    
         | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
      
 197 
     | 
    
         
            +
            	  before :setup_user, :only => :foo
         
     | 
| 
      
 198 
     | 
    
         
            +
            	  before lambda {|c| c.headers['X-Foo] = 'bar' }, :exclude => [:foo, :baz]
         
     | 
| 
       197 
199 
     | 
    
         | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
      
 200 
     | 
    
         
            +
            	  def setup_user
         
     | 
| 
      
 201 
     | 
    
         
            +
            	    # blah blah
         
     | 
| 
      
 202 
     | 
    
         
            +
            	  end
         
     | 
| 
       201 
203 
     | 
    
         | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
      
 204 
     | 
    
         
            +
            	  def foo
         
     | 
| 
      
 205 
     | 
    
         
            +
            	    # blah
         
     | 
| 
      
 206 
     | 
    
         
            +
            	  end
         
     | 
| 
       205 
207 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
      
 208 
     | 
    
         
            +
            	  def regular_action
         
     | 
| 
      
 209 
     | 
    
         
            +
            	    # blah
         
     | 
| 
      
 210 
     | 
    
         
            +
            	  end
         
     | 
| 
       209 
211 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
            end
         
     | 
| 
      
 212 
     | 
    
         
            +
            	end
         
     | 
| 
       211 
213 
     | 
    
         | 
| 
       212 
214 
     | 
    
         
             
            To stop the before filter chain you use throw :halt with a few options:
         
     | 
| 
       213 
215 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
            # halts the filter chain and calls filters_halted which you can override 
         
     | 
| 
       215 
     | 
    
         
            -
            # in your controller to specialize it.
         
     | 
| 
      
 216 
     | 
    
         
            +
            	# halts the filter chain and calls filters_halted which you can override 
         
     | 
| 
      
 217 
     | 
    
         
            +
            	# in your controller to specialize it.
         
     | 
| 
       216 
218 
     | 
    
         | 
| 
       217 
     | 
    
         
            -
            throw :halt
         
     | 
| 
      
 219 
     | 
    
         
            +
            	throw :halt
         
     | 
| 
       218 
220 
     | 
    
         | 
| 
       219 
     | 
    
         
            -
            # halts the filters and calls the method named after the symbol:
         
     | 
| 
      
 221 
     | 
    
         
            +
            	# halts the filters and calls the method named after the symbol:
         
     | 
| 
       220 
222 
     | 
    
         | 
| 
       221 
     | 
    
         
            -
            throw :halt, :other_action
         
     | 
| 
      
 223 
     | 
    
         
            +
            	throw :halt, :other_action
         
     | 
| 
       222 
224 
     | 
    
         | 
| 
       223 
     | 
    
         
            -
            # halts the filter chain and returns the result of the Proc being called
         
     | 
| 
      
 225 
     | 
    
         
            +
            	# halts the filter chain and returns the result of the Proc being called
         
     | 
| 
       224 
226 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
            throw :halt, Proc.new{ |c| c.redirect "/foo" }
         
     | 
| 
      
 227 
     | 
    
         
            +
            	throw :halt, Proc.new{ |c| c.redirect "/foo" }
         
     | 
| 
       226 
228 
     | 
    
         | 
| 
       227 
     | 
    
         
            -
            # halts the chain and returns whatever is in the string
         
     | 
| 
      
 229 
     | 
    
         
            +
            	# halts the chain and returns whatever is in the string
         
     | 
| 
       228 
230 
     | 
    
         | 
| 
       229 
     | 
    
         
            -
            throw :halt, "<h1>You don't have permissions dude!</h1>"
         
     | 
| 
      
 231 
     | 
    
         
            +
            	throw :halt, "<h1>You don't have permissions dude!</h1>"
         
     | 
| 
       230 
232 
     | 
    
         | 
| 
       231 
     | 
    
         
            -
            or even render templates:
         
     | 
| 
      
 233 
     | 
    
         
            +
            	or even render templates:
         
     | 
| 
       232 
234 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
            throw :halt, render 'foo'
         
     | 
| 
       234 
     | 
    
         
            -
            throw :halt, partial 'foo'
         
     | 
| 
      
 235 
     | 
    
         
            +
            	throw :halt, render 'foo'
         
     | 
| 
      
 236 
     | 
    
         
            +
            	throw :halt, partial 'foo'
         
     | 
| 
       235 
237 
     | 
    
         | 
| 
       236 
     | 
    
         
            -
            After filters accept a symbol, string or 
     | 
| 
      
 238 
     | 
    
         
            +
            After filters accept a symbol, string or Proc and call that proc with the controller:
         
     | 
| 
       237 
239 
     | 
    
         | 
| 
       238 
     | 
    
         
            -
            after Proc.new {|c| Tidy.new(c.body) }, :only => :index
         
     | 
| 
      
 240 
     | 
    
         
            +
            	after Proc.new {|c| Tidy.new(c.body) }, :only => :index
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            === Sessions
         
     | 
| 
       239 
243 
     | 
    
         | 
| 
       240 
244 
     | 
    
         
             
            Sessions are available when you start merb with the sql_session set to true or the 
         
     | 
| 
       241 
245 
     | 
    
         
             
            memory_session set to true. See generated app for migration too add session table.
         
     | 
| 
       242 
246 
     | 
    
         | 
| 
       243 
     | 
    
         
            -
            Helpers 
     | 
| 
      
 247 
     | 
    
         
            +
            === Helpers
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
            dist/app/helpers/global_helper.rb will be available to all of your views.
         
     | 
| 
       244 
250 
     | 
    
         
             
             Helpers named after your controller plus _helper.rb will be included in the views
         
     | 
| 
       245 
251 
     | 
    
         
             
             for that controller only.
         
     | 
| 
       246 
252 
     | 
    
         | 
| 
       247 
     | 
    
         
            -
             
     | 
| 
      
 253 
     | 
    
         
            +
            === The +merb+ server
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
       248 
255 
     | 
    
         
             
            right now you add your routes in
         
     | 
| 
       249 
256 
     | 
    
         
             
            the appdir/dist/conf/router.rb file. So by default it runs on port 4000
         
     | 
| 
       250 
257 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
            $ cd /path/to/your/merb/app
         
     | 
| 
       252 
     | 
    
         
            -
            $ merb  
         
     | 
| 
      
 258 
     | 
    
         
            +
            	$ cd /path/to/your/merb/app
         
     | 
| 
      
 259 
     | 
    
         
            +
            	$ merb  
         
     | 
| 
       253 
260 
     | 
    
         | 
| 
       254 
261 
     | 
    
         
             
            Or to start merb on a different port:
         
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
            	$ merb -p 3500
         
     | 
| 
       256 
264 
     | 
    
         | 
| 
       257 
265 
     | 
    
         
             
            To start a cluster of merb servers you specify the first port and then how many 
         
     | 
| 
       258 
266 
     | 
    
         
             
            servers you want spawned. SO this command will start a merb instance on ports
         
     | 
| 
       259 
267 
     | 
    
         
             
            3000, 3001, 3002
         
     | 
| 
       260 
268 
     | 
    
         | 
| 
       261 
     | 
    
         
            -
            $ merb -p 3000 -c 3
         
     | 
| 
      
 269 
     | 
    
         
            +
            	$ merb -p 3000 -c 3
         
     | 
| 
       262 
270 
     | 
    
         | 
| 
       263 
271 
     | 
    
         
             
            To start a Merb IRB console where all your models and other classes are pre loaded
         
     | 
| 
       264 
272 
     | 
    
         
             
            use the -i flag
         
     | 
| 
       265 
273 
     | 
    
         | 
| 
       266 
     | 
    
         
            -
            $merb -i
         
     | 
| 
      
 274 
     | 
    
         
            +
            	$merb -i
         
     | 
| 
       267 
275 
     | 
    
         | 
| 
       268 
     | 
    
         
            -
             
     | 
| 
      
 276 
     | 
    
         
            +
            === File uploads
         
     | 
| 
       269 
277 
     | 
    
         
             
            This is one of the things that Merb was written for. Rails doesn't allow 
         
     | 
| 
       270 
278 
     | 
    
         
             
            multiple concurrent file uploads at once without blocking an entire rails backend for each file upload. Merb allows multiple file uploads at once.
         
     | 
| 
       271 
     | 
    
         
            -
             
     | 
| 
      
 279 
     | 
    
         
            +
            When a file is uploaded with Merb, it gets put in a Tempfile. So 
         
     | 
| 
       272 
280 
     | 
    
         
             
            you just want to copy it to the right place on the filesystem.
         
     | 
| 
       273 
281 
     | 
    
         | 
| 
       274 
     | 
    
         
            -
            def upload
         
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
      
 282 
     | 
    
         
            +
            	def upload
         
     | 
| 
      
 283 
     | 
    
         
            +
            	  puts params[:file].inspect
         
     | 
| 
       276 
284 
     | 
    
         | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
      
 285 
     | 
    
         
            +
            	  FileUtils.mv params[:file][:tempfile].path, MERB_ROOT+"/uploads/#{params[:file][:filename]}"
         
     | 
| 
       278 
286 
     | 
    
         | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
     | 
    
         
            -
            end
         
     | 
| 
      
 287 
     | 
    
         
            +
            	  render
         
     | 
| 
      
 288 
     | 
    
         
            +
            	end
         
     | 
| 
       281 
289 
     | 
    
         | 
| 
       282 
290 
     | 
    
         
             
            A file upload will have a hash of params like this:
         
     | 
| 
       283 
     | 
    
         
            -
            { 
         
     | 
| 
       284 
     | 
    
         
            -
            :filename => File.basename(filename),  
         
     | 
| 
       285 
     | 
    
         
            -
            :content_type => content_type,  
         
     | 
| 
       286 
     | 
    
         
            -
            :tempfile => <Tempfile>, 
         
     | 
| 
       287 
     | 
    
         
            -
            :size => File.size(body) 
         
     | 
| 
       288 
     | 
    
         
            -
            }
         
     | 
| 
       289 
291 
     | 
    
         | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
      
 292 
     | 
    
         
            +
            	{ 
         
     | 
| 
      
 293 
     | 
    
         
            +
            	:filename => File.basename(filename),  
         
     | 
| 
      
 294 
     | 
    
         
            +
            	:content_type => content_type,  
         
     | 
| 
      
 295 
     | 
    
         
            +
            	:tempfile => <Tempfile>, 
         
     | 
| 
      
 296 
     | 
    
         
            +
            	:size => File.size(body) 
         
     | 
| 
      
 297 
     | 
    
         
            +
            	}
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
            == Merb app layout
         
     | 
| 
       291 
300 
     | 
    
         | 
| 
       292 
301 
     | 
    
         
             
            A Merb app contains everything it needs to run in production in the 
         
     | 
| 
       293 
302 
     | 
    
         
             
            MERB_ROOT/dist directory. So for deployment you only need to deploy the dist dir. This
         
     | 
| 
         @@ -297,21 +306,21 @@ and DIST_ROOT. MERB_ROOT is the root of the whole tree. And DISTROOT is MERB_ROO 
     | 
|
| 
       297 
306 
     | 
    
         
             
            You will cd into MERB_ROOT to run the merb command line. ANd when you deploy live you
         
     | 
| 
       298 
307 
     | 
    
         
             
            will put the dist dir into another empty MERB_ROOT on the production server.
         
     | 
| 
       299 
308 
     | 
    
         | 
| 
       300 
     | 
    
         
            -
            merb_app:
         
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
       304 
     | 
    
         
            -
             
     | 
| 
       305 
     | 
    
         
            -
             
     | 
| 
       306 
     | 
    
         
            -
             
     | 
| 
       307 
     | 
    
         
            -
             
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
     | 
    
         
            -
             
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
             
     | 
| 
       312 
     | 
    
         
            -
             
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
             
     | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
      
 309 
     | 
    
         
            +
            	merb_app:
         
     | 
| 
      
 310 
     | 
    
         
            +
            	  Rakefile
         
     | 
| 
      
 311 
     | 
    
         
            +
            	  README
         
     | 
| 
      
 312 
     | 
    
         
            +
            	  scripts
         
     | 
| 
      
 313 
     | 
    
         
            +
            	  test
         
     | 
| 
      
 314 
     | 
    
         
            +
            	    spec
         
     | 
| 
      
 315 
     | 
    
         
            +
            	    unit
         
     | 
| 
      
 316 
     | 
    
         
            +
            	  plugins
         
     | 
| 
      
 317 
     | 
    
         
            +
            	  dist
         
     | 
| 
      
 318 
     | 
    
         
            +
            	    app
         
     | 
| 
      
 319 
     | 
    
         
            +
            	      controllers
         
     | 
| 
      
 320 
     | 
    
         
            +
            	      models
         
     | 
| 
      
 321 
     | 
    
         
            +
            	      views
         
     | 
| 
      
 322 
     | 
    
         
            +
            	    conf
         
     | 
| 
      
 323 
     | 
    
         
            +
            	    lib
         
     | 
| 
      
 324 
     | 
    
         
            +
            	    public
         
     | 
| 
      
 325 
     | 
    
         
            +
            	    plugins
         
     | 
| 
      
 326 
     | 
    
         
            +
            	    schema
         
     |