<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>casperfabricius.com &#187; engines</title>
	<atom:link href="http://casperfabricius.com/site/category/engines/feed/" rel="self" type="application/rss+xml" />
	<link>http://casperfabricius.com/site</link>
	<description>expert ruby on rails development</description>
	<lastBuildDate>Sun, 06 Jun 2010 08:43:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Hello Merb</title>
		<link>http://casperfabricius.com/site/2009/01/01/hello-merb/</link>
		<comments>http://casperfabricius.com/site/2009/01/01/hello-merb/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 15:46:32 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/cfp/casperfabricius.com/site/wp-content/plugins/autometa/autometa.php</b> on line <b>324</b><br />
		<category><![CDATA[engines]]></category>
		<category><![CDATA[radiant]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsconf]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=158</guid>
		<description><![CDATA[Merb is getting merged into Ruby on Rails. Together they will become Rails 3, as announced by David Heinemeier Hansson here and Yehuda Katz here.
I wish I could claim to have been playing with Merb for a while and have some real insight into the framework, but to be honest, I haven&#8217;t. I still think [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.merbivore.org/">Merb</a> is getting merged into <a href="http://www.rubyonrails.com">Ruby on Rails</a>. Together they will become Rails 3, as announced by David Heinemeier Hansson <a href="http://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3">here</a> and Yehuda Katz <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">here</a>.</p>
<p>I wish I could claim to have been playing with Merb for a while and have some real insight into the framework, but to be honest, I haven&#8217;t. I still think this a very interesting news, though, and in my opinion this can only be good news for the Rails community. Already, the brilliant Merb guys are optimizing and improving Rails, for instance <a href="http://yehudakatz.com/2008/12/27/status-memorandum/">this 8% speed boost in using <code>respond_to</code></a>.</p>
<p>So, how can we expect the the merge to affect the Rails framework we know and love? Let&#8217;s peek into the possibilities of combining these two frameworks.</p>
<p><span id="more-158"></span></p>
<p>One change that seems certain, is changes to the <b>routing system</b>. &#8220;Plans are already underway to port the Merb router over to Rails. At the very least, you will have the option to use the Merb DSL syntax instead of the Rails hash-based syntax. We’ll see which one becomes the default.&#8221; Katz <a href="http://yehudakatz.com/2008/12/29/another-rails-2x3-update/">says</a>. David <a href="http://www.loudthinking.com/posts/37-bringing-merbs-providesdisplay-into-rails-3">explains</a> how Merb concepts for rendering resources in different formats will be used in Rails 3, but with more intuitive or &#8220;Rails-like&#8221; naming.</p>
<p>Another change which is likely to make it into Rails 3 is <b>slices</b>, as indicated by Katz in a response to his own <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">announcement</a>. Slices are &#8220;similar to what Rails-Engines promise, except merb-slices are built into the framework&#8221; as Ezra Zygmuntowicz <a href="http://brainspl.at/articles/2008/05/21/merb-slices">explains</a>. This is exiting news! I&#8217;ve always been interested gaining leverage by having reusable application slices, and I&#8217;ve actively built and used both <a href="http://rails-engines.org/">Rails Engines</a> and <a href="http://casperfabricius.com/site/2007/07/19/advanced-radiant-extensions/">Radiant extensions</a>. Engines has previously been frowned upon by leading figures in the Rails community, but it has been improved to work in a quite clean and easy-to-understand manner since the release of Rails 2.0, and are in fact compared to Merb slices <a href="http://rails-engines.org/news/2008/05/24/merb-slices-again/">here</a>. Radiant extensions are obviously only for Radiant CMS-based websites, but the <a href="http://ext.radiantcms.org/extensions">diversity</a> of these extensions illustrates the potential of getting support for real full-stack application slices into the Rails core. A project like <a href="https://github.com/svenfuchs/adva_cms/tree">Adva CMS</a> also illustrates how it is possible to build high quality reusable application slices for the common good.</p>
<p>A third change I hope to see as a result of the merge is <b>controller-based mailers and partials</b>. <code>ActionMailer</code> has always been a bit of an ugly stepchild in the Rails framework, and the positioning of a <code>Mailer</code> as a sort-of model, but with templates, doesn&#8217;t seem logic to me. Merb has an <code>AbstractController</code> class that both mailers and partials (called parts in Merb) inherit from, which allows for a more intuitive control in rendering mails and parts.</p>
<p>I was curious to find out how the Merb community has reacted to this decision. The Rails community doesn&#8217;t seem to be overly concerned. Perhaps it&#8217;s because the merge of Merb and Rails are called &#8220;Rails 3&#8243;. Not &#8220;Merb 2&#8243;, not &#8220;MerbRails&#8221; &#8211; the names clearly signals that the merge will be done on Rails&#8217; terms. While it has become popular in the Rails community to dissociate one self with David Heinemeier Hansson, I still think people sees him as a good security for not letting the Rails principles go in the merge.</p>
<p>I browsed through the more than 100 comments to <a href="http://yehudakatz.com/2008/12/23/rails-and-merb-merge/">Yehuda Katzs announcement</a> of the merge, and while about half of the commenters simply expresses their happiness and agreement with the decision, the objections of the other half falls roughly into three categories: Technical, personal and economic.</p>
<p>The <b>technical concerns</b> are of course fully expected, and some of the more interesting are:</p>
<ul>
<li>&#8220;Does merging a lightweight framework into a bloated framework make the bloated framework any lighter?&#8221;</li>
<li>&#8220;I really hope that merb will be able to continue it’s ‘no-magic’ attitude and bring that to rails without compromises&#8221;</li>
<li>&#8220;I would have liked to see merb go further on its own just to push the envelope further&#8221;</li>
<li>&#8220;How many planned advancements are being put on hold while Rails catches up?&#8221;</li>
</ul>
<p>The <b>personal objections</b> is about one very visible person: David Heinemeier Hansson. I hold no grudge against David, so I shall only repeat one of the more curious comments in this category: &#8220;The big problem, as always with Rails, is DHH: a vainglorious, two-faced prima donna with a massive and fragile ego. He’s good, but not nearly as unique and amazing as he thinks he is. I went to Merb to get away from DHH. Ugh.&#8221; If many people in the Merb community feels like this guy, I understand if they are concerned that David will simply steamroller the philosophy of Merb. David has been fast to <a href="http://www.loudthinking.com/posts/36-work-on-what-you-use-and-share-the-rest">address these concerns</a>, but the question is if just saying everyone should work on what the care about is enough.</p>
<p>The <b>economic perspective</b> of the merge is where things gets interesting. Rails is trademarked by David and synonymous with <a href="http://www.37signals.com">37signals</a>, while Merb is very closely linked to <a href="http://www.engineyard.com">EngineYard</a>. Two commenters really nail it down:</p>
<ul>
<li>&#8220;How has the ‘Opinionated Software’ philosophy of “Fuck You (DHH)” Rails become aligned with the ‘open’ and democratic philosophy of Merb? Is this some kind of preemptive marketing in advance of a joint investment in both Engine Yard and 37 Signals by a common investor?&#8221;</li>
<li>&#8220;My suspicion turns to the fact that almost every Merb core team member is owned by Engine Yard. Something doesn’t smell right.&#8221;</li>
</ul>
<p>It&#8217;ll be interesting to follow not just the architectural design choices made on the technical front during the merge process, but also how this will change the positioning of 37signals and EngineYard, and if the two companies are really warming up to some kind of close relationship.</p>
<p>The timeline for a first peek at Rails 3 &#8211; the union of Merb and Rails &#8211; is <a href="http://merbist.com/2008/12/23/rails-and-merb-merge/">said</a> to be RailsConf 2009 &#8211; 4 months from now.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2009/01/01/hello-merb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Advanced Radiant extensions</title>
		<link>http://casperfabricius.com/site/2007/07/19/advanced-radiant-extensions/</link>
		<comments>http://casperfabricius.com/site/2007/07/19/advanced-radiant-extensions/#comments</comments>
		<pubDate>Thu, 19 Jul 2007 16:29:18 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[engines]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category>radiant</category>
	<category>extension</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2007/07/19/advanced-radiant-extensions/</guid>
		<description><![CDATA[Radiant is probably the best Ruby on Rails content management system (CMS) available at the moment. I&#8217;m using it in several customer projects, and while Radiant is still quite limited and aims to stay that way, it is quite easy to extend and blend with ordinary Rails resources through its pendant to engines; extensions.
Like engines, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://radiantcms.com/">Radiant</a> is probably the best Ruby on Rails content management system (CMS) available at the moment. I&#8217;m using it in several customer projects, and while Radiant is still quite limited and aims to stay that way, it is quite easy to extend and blend with ordinary Rails resources through its pendant to <a href="http://rails-engines.org/">engines</a>; <a href="http://wiseheartdesign.com/2006/12/6/rails-needs-something-better-than-engines/">extensions</a>.</p>
<p>Like engines, extensions allows developers to share not just &#8220;plain&#8221; Ruby code between applications (which is done through plugins), but also to share controllers, views and routes between them, as well as maintaining separate migration versions for each extension. One difference between engines and extensions I&#8217;ve spotted, is that while engines allows the developer to override and add individual actions in controllers, extensions allow only for replacing an entire controller.</p>
<p>Recently, <a href="http://wiseheartdesign.com/">John W. Long</a>, creator of Radiant, wrote <a href="http://wiki.radiantcms.org/Creating_Radiant_Extensions">a nice tutorial on the basics of extensions</a>, so if you haven&#8217;t had a look at that, I&#8217;d recommend it before proceeding with this article. The rest of this text puts focus on how to alter the behavior of Radiant to suit your needs by developing an extension.</p>
<p>I&#8217;ll use one of my own extensions, the first to be published as open-source; <a href="http://svn.casperfabricius.com/extensions/file_based_layout/">File Based Layout</a>, as an example on how to override, modify and add functionality to the core of Radiant. I developed this extension to bridge a critical gap between &#8220;static&#8221; Radiant pages and &#8220;dynamic&#8221; Rails pages; the non-existent ability to let them share the same layout. To achieve this, I had to alter the <code>Layout</code> model and the <code>Site</code>- and <code>LayoutControllers</code>. This is possible through the dynamic nature of Ruby, but it requires some knowledge about &#8220;metaprogramming&#8221; which I for one didn&#8217;t have before I started to develop extensions.</p>
<p>Take a look at <code><a href="http://svn.casperfabricius.com/extensions/file_based_layout/file_based_layout_extension.rb">file_based_layout_extension.rb</a></code>.  The <code>activate</code> method, invoked by Radiant at the proper time, includes code in the <code>Layout</code> model and the <code>Site</code>- and <code>LayoutControllers</code> located in modules placed in the <code>lib</code> directory of the extension:</p>
<pre>
  def activate
    Layout.send :include, FileBasedLayout::LayoutExt
    SiteController.send :include, FileBasedLayout::SiteControllerExt
    Admin::LayoutController.send :include, FileBasedLayout::LayoutControllerExt
  end
</pre>
<p>As other extensions might also want to extend models and controllers using similar module names, I have opted to namespace the modules with <code>FileBasedLayout</code>. Also, to make the three modules available to <code>file_based_layout_extension.rb</code>, they have to be required using <code>require_dependency</code> as I have in the top of the file.</p>
<p>To be able to store the name of a physical layout file with the Radiant Layout, I had to add a field the <code>layouts</code> table; <code>layout_file</code>. This is done by adding a migration file to the <code>db/migrate</code> directory, and running the command <code>rake db:migrate:extensions</code>. I also wanted to validate the length of this field, and add a convenience method to the <code>Layout</code> model called <code>file_based?</code> (can you guess what it does?). This is done in the <code>self.included</code> method in <code>layout_ext.rb</code> by invoking <code>base.class_eval</code> with a block of code to be added to the class:</p>
<pre>
    def self.included(base)
      base.class_eval {
        validates_length_of :layout_file, :allow_nil => true, :maximum => 100, :message => '%d-character limit'
        include InstanceMethods
      }
    end

    module InstanceMethods
      def file_based?
        ! layout_file.nil? &#038;&#038; ! layout_file.empty?
      end
    end
</pre>
<p>This is pretty simple, as we are merely <i>adding</i> stuff to the <code>Layout</code> class, but if what if we wanted to <i>override</i> stuff of, say, the <code>SiteController</code>? To create the File Based Layout extension, I needed to override some pretty low-level stuff in Radiant, in particular the <code>show_uncached_page</code> method, which is invoked when Radiant gets a request for a page not placed in the cache. It&#8217;s not enough to just include a module with this method, as I do in <code><a href="http://svn.casperfabricius.com/extensions/file_based_layout/lib/layout_controller_ext.rb">layout_controller_ext.rb</a></code>, as methods in the class takes precedence over included methods.</p>
<p>Instead, I had to place my new <code>show_uncached_page</code> method directly inside the block given to <code>base.class_eval</code> in <code><a href="http://svn.casperfabricius.com/extensions/file_based_layout/lib/site_controller_ext.rb">site_controller_ext.rb</a></code>. This way, the new method is, so to speak, placed last in the <code>SiteController</code> class, overriding previous definitions of the method:</p>
<pre>
def self.included(base)
  base.class_eval {
    private

    def show_uncached_page(url)
      @page = find_page(url)
      unless @page.nil?
        if @page.layout &#038;&#038; @page.layout.file_based?
          render :text => process_with_file_based_layout(@page), :layout => File.basename(@page.layout.layout_file, File.extname(@page.layout.layout_file))
        else
		...
   end

   ...

  }
end
</pre>
<p>And that&#8217;s it, really. When extending and changing Radiant or other Rails applications, the <code>include</code>, <code>self.included</code> and <code>base.class_eval</code> methods are your friends. There are, of course, performance penalties connected with especially <code>class_eval</code>, but as Radiant pages are cached, we don&#8217;t have to care too much about them.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2007/07/19/advanced-radiant-extensions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Inside Rails Engines</title>
		<link>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/</link>
		<comments>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/#comments</comments>
		<pubDate>Sun, 06 Aug 2006 20:36:29 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[engines]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>article</category>
	<category>engines</category>
	<category>title</category>
	<category>aimed</category>
	<category>pure</category>
	<category>parts</category>
	<category>curiosity</category>
	<category>diving</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/08/06/inside-rails-engines/</guid>
		<description><![CDATA[Rails Engines are small subsets of an application that can be dropped into any of your Rails applications and handle common parts of the application from scratch. The title might be a bit misleading, since the technical side of this article is really a beginner’s introduction to Rails Engines spiced up with a few tips [...]]]></description>
			<content:encoded><![CDATA[<p>Rails Engines are small subsets of an application that can be dropped into any of your Rails applications and handle common parts of the application from scratch. The title might be a bit misleading, since the technical side of this article is really a beginner’s introduction to Rails Engines spiced up with a few tips and tricks. I&#8217;m not diving into the inner workings of engines &#8211; the &#8220;inside&#8221; part of the title is more aimed against the fact that I&#8217;ve &#8211; out of pure curiosity and as a preparation for this article &#8211; asked the author of the engine plugin and the first and still most popular engines; James Adam, a few questions about his thoughts behind the engines and which direction he wants them to go in.</p>
<p><b>What is an engine?</b><br />
There are two aspects of Rails Engines: There&#8217;s <i>the</i> engine plugin, a standard Rails plugin that you need to install as any other plugin. This plugin enables you install the individual actual engines that you want to use &#8211; the engines are also seen as standard plugins from Rails&#8217; point of view, but they won&#8217;t work without the engine plugin.</p>
<p>An engine works by allowing a large part of the standard Rails application structure (that is; the <code>/app</code> directory in your projects) to exist as a part of the engine. Where a normal plugin only compromises Ruby code (often core extensions and helper classes), an engine are capable of having controllers, views and models that behaves like they are situated in the &#8220;real&#8221; <code>/app</code> directory.</p>
<p>This allows you to reuse a lot of traditional support functionality such as authentication, authorization and user management, a wiki, a shopping basket, a blog, a CMS and so on. Several engine implementations of some of this functionality already exist, most of which can be found through <a href="http://rails-engines.org/">Rails-Engines.org</a>, and while the wonders of CSS can get you a long way in getting these engines to fit into the design of the rest of your app, you will almost certainly want to change some things. Enter Rails Engine&#8217;s biggest advantage: The ability to override individual views and controller actions on a pr. need basis.</p>
<p>Let&#8217;s say you want to add some text and images to the login view of the Login engine, because this action effectively will function as your frontpage. All have to do is to copy the view from the <code>/app/views</code> directory of the engine into the corresponding directory in your own <code>views</code> directory &#8211; and through the magic of the engine plugin, this view now <em>overrides</em> the view that came with the engine. Often you&#8217;ll also need to modify the behavior of various actions supplied by the engine &#8211; you do this simply by creating a controller with the same name as the controller in the engine with action you want to override in your own <code>/app/controllers</code> directory, and define the actions in the controller. The engine plugin is able to combine the controllers of the engine with the ones in your app, so you can both override actions already defined by the engine, and you can add actions to a controller defined by the engine.</p>
<p><b>When should you use an engine?</b><br />
While it is indeed very convenient to be able to drop all this functionality into your app without writing any code your self, you should be aware that this ability is not the primary goal with the original engine plugin, and that many people sees a lot of potential problems in constructing an application from one or more engines. James Adam explained it like this to me in an email:</p>
<blockquote><p>Rails and Ruby make developing applications very easy, so there&#8217;s very little reason why a competent developer couldn&#8217;t write every part of the application that they need, and not rely on any  code from outside. Working in this way has significant benefits, because it puts you in a position where you intimately understand exactly how your application works. There are no mysterious black boxes.</p></blockquote>
<p>So when should you use an engine? James&#8217; original intention with Rails Engines, and the way he continues to use them himself, is by abstracting commonly used application &#8220;chunks&#8221; so they can be reused in his company&#8217;s applications:</p>
<blockquote><p>Where I work, we are working on a varying collection of fundamentally similar applications, all at the same time. They don&#8217;t have widely different requirements in terms of their basic architecture (authentication, importing Excel data, reporting back, loading and storing data and so on&#8230;), so it makes sense that we only maintain a single version of each of these shared aspects. &#8220;Enterprise DRY&#8221;, if you like. This is why engines exists; we wrote the engines plugin to make it possible for use to reuse as much of this shared code as made sense in our situation, in a manner that was easy to maintain where generators aren&#8217;t, but easy to override when the situation required it.</p></blockquote>
<p>As for myself, I gladly use the Login, User, Riki and Substruct engines in several applications, and while I cannot claim that it haven&#8217;t taken an effort to integrate the engines into the application, I&#8217;d still say that it has saved me a considerable amount of time &#8211; especially when I&#8217;m reusing an engine that I already know well. I guess the ultimate DRY-proof solution would be to abstract my own versions of these engines &#8211; probably not to share with others, but use in my own projects working just the way I want them.</p>
<p><b>Implementing the Login and User engines in your application</b><br />
Now to the more tutorial-ish aspects of this article. In this section, I&#8217;ll explain how to implement two of the most commonly used engines in your application. I expect you to have a running Rails application with a functional database connection. I also suggest that you setup a Subversion repository so you can add the plugins as externals, but it is not strictly necessary, just DRY&#8217;er.</p>
<ol>
<li>
		Install the Engine plugin</p>
<ol>
<li>Setup an SVN external attribute to point <code>vendor/plugins/engines</code> to <a href="http://svn.rails-engines.org/engines/tags/rel_1.1.3/">http://svn.rails-engines.org/engines/tags/rel_1.1.3/</a> (or just download the files to that directory).</li>
<li>The engine plugin is automatically loaded by Rails, and nothing visible happens until you install some engines. However, if you are running engines on Edge Rails, you should add this to the very top of <code>config/environment.rb</code>:
<pre style="width:300px;">
# environment.rb
module Engines
  CONFIG = {:edge => true}
end
</pre>
</li>
</ol>
</li>
<li>Install the Login and User engines
<ol>
<li>Setup SVN external attributes to point <code>vendor/plugins/login_engine</code> to <a href="http://svn.rails-engines.org/login_engine/tags/rel_1.0.2/">http://svn.rails-engines.org/login_engine/tags/rel_1.0.2/</a> and <code>vendor/plugins/user_engine</code> to <a href="http://svn.rails-engines.org/user_engine/tags/rel_1.0.1/">http://svn.rails-engines.org/user_engine/tags/rel_1.0.1/</a>.</li>
<li>Create two new migrations; <code>login_engine_schema</code> and <code>user_engine_schema</code>, and copy the contents of the migration(s) in the <code>db/migrations</code> of each engine into each of the new migrations. This way, you can still create the entire database structure with the <code>rails migrate</code>, without the need for running specialized engine tasks.</li>
<li>Add the required configuration and startup code to <code>config/environment.rb</code>. The configuration is well documented in the read me files, so I won&#8217;t dive into that here, but instead provide a sample of my setup:
<pre style="width:400px">
# environment.rb

#####################################################
# Engine setup
#####################################################

module LoginEngine
  config :salt, "not_my_real_salt"
  #...
end

module UserEngine
  config :admin_login, "admin"
  #...
end

Engines.start :login, :user

UserEngine.check_system_roles
Permission.sync rescue false # Ignore any errors here
</pre>
</li>
<li>Add code to <code>application.rb</code> in order to add user authorization to all actions, and to make the user-logic available to helpers and models:
<pre style="width:400px">
# application.rb

require 'login_engine'
require 'user_engine'

class ApplicationController < ActionController::Base

  # Login and User Engines setup
  include LoginEngine
  include UserEngine
  helper :user
  model :user
  before_filter :authorize_action # unless RAILS_ENV == 'test'

end
</pre>
<p>(Be sure to also include Login- and UserEngine in <code>application_helper.rb</code> to make support available to the views.)
</li>
</ol>
</li>
<li>Override views, actions and models as needed</li>
<ul>
<li>A view is overridden by creating a view with the same name in your own app-structure - <i>not</i> by modifying the view directly in the engine. For example; if you want to override the template for the <code>list</code> action of the <code>user</code> controller, simply create the file <code>list.rhtml</code> in <code>/app/views/user/</code>, and this file will be used.</li>
<li>An action is overridden by creating the controller the action belongs to, and defining a function with the same name. For example; if you want to override the <code>list</code> action of the <code>UserController</code> to provide additional data to your list view, you should create the <code>user_controller.rb</code> file in <code>/app/controllers/<code> and define the action:
<pre style="width:400px;">
# user_controller.rb

def list
  # ...
end
</pre>
</li>
<li>Overriding a model is a bit more complicated, since the engine plugin has no clever way of supporting this due to <a href="http://rails-engines.org/wiki/pages/Why+Models+Don%27t+Act+Like+Controllers">various reasons</a>. However, in the Login- and User engines, it is possible to extend the User-model because it is implemented as a namespaced module, which can be included in your own model-file. So if you want to associate a user with, say, a log entry, you can create the file <code>/app/models/user.rb</code> with this code:
<pre style="width:400px;">
# user.rb

class User < ActiveRecord::Base
  include LoginEngine::AuthenticatedUser
  include UserEngine::AuthorizedUser

  has_many :log_entries

end
</pre>
</li>
</ul>
</ol>
<p><b>Tips and tricks</b><br />
Many people complain that it is hard to test your application with authentication and authorization enabled. The easy solution is to add <code>unless RAILS_ENV == 'test'</code> to the <code>before_filter :authorize_action</code> line in <code>application.rb</code>. The better solution is to actually have a loaded user during the tests, since this is what the application generally expects. One way to solve this is to put this in your test case:</p>
<pre>
# /test/fixtures/companies_controller.rb

  def setup
    @controller = CompaniesController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
    @request.session[:user] = User.find(1)
  end
</pre>
<p>Another issue the synchronization of the permissions data for the User engines authorization logic. I'm not entirely happy with the way this work, since the <code>Permission.sync</code> done on system startup tends to fail, which is why I've had to add <code>rescue false</code> to ignore any errors.</p>
<p><b>Some final thoughts</b><br />
Should the standard Rails plugins go in the direction of engines? I asked James Adam this very question, and here is what he answered:</p>
<blockquote><p>
Yes and no. Some things that I feel should be easier in plugins:</p>
<ul>
<li>Managing stylesheets/javscripts/etc in plugins. The engines plugin makes this trivial, and I'll be working on adapting the implementation of this feature so it seems natural in any plugin.</li>
<li>Sharing views in plugins. While you can do that with a plugin (overriding a controller's template_root), that seems like a bit of a kludge. I'd like to see a 'load_path' for views.</li>
</li>
<li>Controlling whether plugins are loaded or not. This is handy for development, and as a side effect, you get control over the plugin load order.</li>
</ul>
<p>What shouldn't be a part of the default plugin system:</p>
<ul>
<li>Overriding aspects of controllers, helpers and views automagically. This behavior is significantly different  from that way that Rails works in a normal situation. Because of this, users should explicitly 'ask' (by installing/creating engines-based plugins) for this behavior, so they know what to expect. This is really the significant addition that engines add beyond what might seem natural for a plugin anyway.</li>
</ul>
</blockquote>
<p>Thank you for Rails Engines, James, and keep up the good work!</p>
<p><b>Additional resources</b></p>
<ul>
<li><a href="http://rails-engines.org/">Home of Rails Engines</a></li>
<li><a href="http://alterlabs.com/ruby/how-to-build-a-ruby-on-rails-engine-in-depth-start-to-finish-tutorial">How to write your own Rails Engine</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/08/06/inside-rails-engines/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
