root/tags/0.3.1/README

Revision 216, 9.0 kB (checked in by e.@brainspl.at, 2 years ago)

updating readme and added stream_file for streaming

  • Property svn:executable set to
Line 
1
2 Copyright (c) 2006 Ezra Zygmuntowicz
3
4 Merb.
5
6 Lightweight MVC Ruby app server. For high performance dynamic pages.
7
8 ** Dependencies **
9 mongrel
10 erubis
11 json or fjson
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
21
22 To generate a new merb app after the gem is installed:
23 $ merb -g myapp
24
25
26 **FEATURES**
27
28 *Mongrel handler*
29 built in that parses incoming requests
30 including multipart uploads and post as well as ?query=strings. Puts the
31 params into params and the cookies into cookies when it instantiates your
32 controller class.
33
34 *RouteMatcher and route compiler*
35
36 Reads your route definition and compiles
37 a method on the fly that will match the request path against each route and do the right thing.
38
39 *** NEW RESTFULL ROUTES ***
40
41 note the r.resource :posts macro. That makes it possible to use a restfull crud style controller for the posts resource
42
43 Merb::RouteMatcher.prepare do |r|
44   r.resources :posts
45   r.default_routes
46   r.add '/', :controller => 'files', :action => 'index'
47 end
48
49 The r.default_routes routes adds the standard routes:
50
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
57
58
59
60 *Controllers*
61 Classes with built in render method and template handling
62 with instance vars available in the views automatically. Merb also supports
63 layouts. It will look for a layout named after your controller class first and
64 then fall back to application.herb if no layout exists named after your controller.
65 You can use render :layout => :none.
66
67 Merb does not automatically render for you in your controller actions, you have
68 to call render yourself. I consider this a big advantage over the way rails does
69 it for a few reasons. The main reason is that in rails you can only render once
70 per action, so it knows if you haven’t rendered it shoudl auto render. Merb on
71 the other hand, returns to the browser whatever the return value of your
72 controller’s action method is. This opens up more possibilities imho because
73  now you can return any string from your action and that will be sent down
74 the pipe. So Merb’s render method just returns a string and needs to be the
75 last thing you call in your action. You can render multiple times and capture
76 the results into @ivars and then render a master template with many embeded
77 templates. Also if you return a handle on a File or IO object from your action
78 then merb will hand that over to mongrel to be streamed out to the client. And
79 if you return a Proc object from your action, it will be called and the
80 return value sent to the client.
81
82 That last point has some cool connotations if you think about it. Merb does
83 have a mutex lock around the call to your controller’s action anywhere that
84  you can call AR objects. Merb’s lock is way smaller then rails giant lock
85 though and allows for many more concurrent requests to be handled by one
86 process. By returning a Proc object from your action, you allow merb to
87 release the lock and the proc is called in multi threaded way. This allows
88 for all kinds of cool streaming and ‘futures’ where you return the proc and
89 release the mutex. It’s basically like handing over the proc to mongrel and
90 mongrel handles calling it in a thread safe manner.
91
92
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
101 You can also render partials like so:
102 <%= partial(:comments) %>
103
104 This assumes a _comments.rhtml file in the same view dir as the current
105 controller/view
106
107 Partials compile the template ands returns a string. So you can also call
108 them and assign them to a var if you want:
109
110 def someaction
111   @one = partial(:one)
112   @two = partial(:two)
113 end
114
115 partials can also render views from other controllers by specifying the path
116
117 partial('/shared/foo')
118
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
142 *Restful Controllers*
143
144 restful controllers use a different dispatch system based on the request method verbs. Merb
145 supports multi return values based on the accept header via respond_to
146
147 class Posts < Merb::Controller
148   # GET /posts
149   # GET /posts.xml
150   def index
151     @posts = Post.find :all
152     respond_to {|format|
153       format.html { render }
154       format.js   { render :js => 'index' }
155       format.xml  { render :xml => @posts.to_xml }
156     }
157   end
158
159   # GET /posts/1
160   # GET /posts/1.xml
161   def show
162   end
163
164   # GET /posts/new
165   def new
166   end
167
168   # GET /posts/1;edit
169   def edit
170   end
171
172   # POST /posts
173   # POST /posts.xml
174   def create
175   end
176
177   # PUT /posts/1
178   # PUT /posts/1.xml
179   def update
180   end
181
182   # DELETE /posts/1
183   # DELETE /posts/1.xml
184   def destroy
185   end
186 end
187
188
189 *Controllers have powerful before and after filters*
190
191 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
193 class Foo < Merb::Controller
194  
195   before :setup_user, :only => :foo
196   before lambda {|c| c.headers['X-Foo] = 'bar' }, :exclude => [:foo, :baz]
197
198   def setup_user
199     # blah blah
200   end
201
202   def foo
203     # blah
204   end
205
206   def regular_action
207     # blah
208   end
209
210 end
211
212 To stop the before filter chain you use throw :halt with a few options:
213
214 # halts the filter chain and calls filters_halted which you can override
215 # in your controller to specialize it.
216
217 throw :halt
218
219 # halts the filters and calls the method named after the symbol:
220
221 throw :halt, :other_action
222
223 # halts the filter chain and returns the result of the Proc being called
224
225 throw :halt, Proc.new{ |c| c.redirect "/foo" }
226
227 # halts the chain and returns whatever is in the string
228
229 throw :halt, "<h1>You don't have permissions dude!</h1>"
230
231 or even render templates:
232
233 throw :halt, render 'foo'
234 throw :halt, partial 'foo'
235
236 After filters accept a symbol, string or   Proc and call that proc with the controller:
237
238 after Proc.new {|c| Tidy.new(c.body) }, :only => :index
239
240 Sessions are available when you start merb with the sql_session set to true or the
241 memory_session set to true. See generated app for migration too add session table.
242
243 Helpers: dist/app/helpers/global_helper.rb will be available to all of your views.
244  Helpers named after your controller plus _helper.rb will be included in the views
245  for that controller only.
246
247 *The merb server*
248 right now you add your routes in
249 the appdir/dist/conf/router.rb file. So by default it runs on port 4000
250
251 $ cd /path/to/your/merb/app
252 $ merb 
253
254 Or to start merb on a different port:
255 $ merb -p 3500
256
257 To start a cluster of merb servers you specify the first port and then how many
258 servers you want spawned. SO this command will start a merb instance on ports
259 3000, 3001, 3002
260
261 $ merb -p 3000 -c 3
262
263 To start a Merb IRB console where all your models and other classes are pre loaded
264 use the -i flag
265
266 $merb -i
267
268 *File uploads*
269 This is one of the things that Merb was written for. Rails doesn't allow
270 multiple concurrent file uploads at once without blocking an entire rails backend for each file upload. Merb allows multiple file uploads at once.
271  When a file is uploaded with Merb, it gets put in a Tempfile. So
272 you just want to copy it to the right place on the filesystem.
273
274 def upload
275   puts params[:file].inspect
276  
277   FileUtils.mv params[:file][:tempfile].path, MERB_ROOT+"/uploads/#{params[:file][:filename]}"
278
279   render
280 end
281
282 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
290 *Merb app layout*
291
292 A Merb app contains everything it needs to run in production in the
293 MERB_ROOT/dist directory. So for deployment you only need to deploy the dist dir. This
294 keeps your test code and development plugins separate from your main app and lets you
295 not deploy them to the live server. You deal with two things with this setup, MERB_ROOT
296 and DIST_ROOT. MERB_ROOT is the root of the whole tree. And DISTROOT is MERB_ROOT+/dist
297 You will cd into MERB_ROOT to run the merb command line. ANd when you deploy live you
298 will put the dist dir into another empty MERB_ROOT on the production server.
299
300 merb_app:
301   Rakefile
302   README
303   scripts
304   test
305     spec
306     unit
307   plugins
308   dist
309     app
310       controllers
311       models
312       views
313     conf
314     lib
315     public
316     plugins
317     schema
Note: See TracBrowser for help on using the browser.