|
Re: RESTful mixin, mixin repo?: msg#00027lang.ruby.camping.general
Mark Fredrickson wrote: > [...] I want: entire MVC stacks that I can drop into different apps - > eg. a user login engine that works in any app a /user and provides > some useful predicates - is_logged_in?, etc...) I've had a look at this and think I've found something like a solution. The Controllers and Models don't seem to be much of an issue, the Views are a little more problematic. Read on for the details. # Views Camping.goes :NewApp module NewApp module Views; include OtherApp::Views; end end Doesn't work because NewApp::Views is included into NewApp::Mab *before* the inclusion of OtherApp::Views. As a result the OtherApp::Views methods are *not* included in the NewApp::Mab class and so are not available for controllers/other view methods to call. At least I *think* that's what's happening. Camping.goes :NewApp module NewApp class Mab; include OtherApp::Views; end end Works, but you can't override OtherApp's views in NewApp. If OtherApp includes a layout then you're stuck with it (unless you change it under the Mab class in NewApp rather than Views). # Create the NewApp module and include the OtherApp's Views into it module NewApp module Views; include OtherApp::Views; end end # Stir in Camping goodness Camping.goes :NewApp # Write the NewApp, freely using the views from OtherApp module NewApp # ... models, views, controllers, etc. end Works, and is somewhat less coupled to Camping's implementation. A benefit of this is that you can override any of OtherApp's views in NewApp (e.g. overriding the layout) without leaving the cosy confines of the Views module. # Controllers Camping.goes :NewApp module NewApp module Controllers; include OtherApp::Controllers; end end Works. Doing the include before Camping.goes, as in Views above, also works. # Models Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end include OtherApp # for the create method end Doesn't work -- the OtherApp.create singleton method isn't included into NewApp (due to the way include works). Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end def self.create Models.create_schema end end Doesn't work, the OtherApp tables don't get created. create_schema doesn't see the schema from OtherApp for some reason. Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end def self.create OtherApp::Models.create_schema end end Works. Tables are created and models from OtherApp can be used in NewApp. Doing the include, and defining self.create, before Camping.goes, as in Views above, also works. # Putting it all together See the attached: campers.rb and campfire.rb. campers.rb is a simple app that exposes a list of campers, campfire.rb extends this with another controller and view, please excuse the campness of it all. The main ingredient is the means by which Campfire includes Campers: module Campfire module Models; include Campers::Models; end module Controllers; include Campers::Controllers; end module Views; include Campers::Views; end module Helpers; include Campers::Helpers; end def self.create; Campers.create; end end This comes *before* the `Camping.goes :Campfire` line. So, if you want to incorporate one Camping app within another the above method seems to be the way to go. Seems a bit verbose though and I don't like that whole "you have to extend the new application before creating it with Camping.goes" thing. How about coercing include to help us out a bit? module Campers def self.included(other_app) %w{Helpers Models Controllers Views}.each do |mod| next unless self.const_defined? mod unless other_app.const_defined? mod other_app.const_set(mod, Module.new) end our_mod = self.const_get(mod) other_app.const_get(mod).class_eval(){include our_mod} end if !other_app.method_defined?('create') \ && self.method_defined?('create') other_app.class_eval( "def self.create; #{self.name}.create; end" ) end end end Hmmm. That's decidedly *more* verbose. But we can now do this: module Campfire; include Campers; end Camping.goes :Campfire # ... Campfire models, views, controllers, etc. So, if we can hide that great big chunk of `included` somewhere out of sight, but where Camping apps can pick it up, we'd be somewhere near to where we want to be. -- Adam
Camping-list mailing list Camping-list-GrnCvJ7WPxnNLxjTenLetw@xxxxxxxxxxxxxxxx http://rubyforge.org/mailman/listinfo/camping-list
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: Re: RESTful mixin, mixin repo?, Jonas Pfenniger |
|---|---|
| Next by Date: | Re: Catching a list of variables with a Controller, Boris Terzic |
| Previous by Thread: | Re: Re: RESTful mixin, mixin repo?, Jonas Pfenniger |
| Next by Thread: | Re: RESTful mixin, mixin repo?, Chris Wanstrath |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |