1. Store Rails views on database

    When it comes to develop a CMS, one of the main problems concerns where or how to store and organize views (templates, partials, layouts) for particular needs like different layouts for specific pages, (sub)domains or multi-languages. The ideal way is to store views on a database, indeed there are some CMSs that solve this problem with similar approaches, like Radiant and Locomotive.

    However, I wanted something that let me to reuse this feature on several projects (because a custom CMS may have different features), and to store only certain views, according to specific content and needs.

    So, I’ve developed Panoramic, a simple gem inspired from some ideas found in José Valim’s excellent book Crafting Rails Applications. Simply put, once Panoramic is installed, you can store your views on database. It works through an implemetation of ActionView::Resolver class: Rails will lookup views as if they were on filesystem. In controller, you’ll tell where and when to use those views, using prepend_view_path and append_view_path on a controller or action basis (they are both implemented as class and instance methods). Depending from the method you’ll use, Rails will respectively look for views on database, then it will fallback on filesystem, or viceversa. Quite easy, right?

    I’ll not show any code here, because there’s a full explanation on Panoramic’s README. As a final note, at the moment it works only with ActiveRecord, but I’ve planned to extend support to DataMapper and Mongoid as soon as possible. It’s very easy to implement, the main problem is about testing: maybe I’ll write some rspec’s custom matchers to reuse with different ORMs, like carrierwave.

  2. Rails 3: An improved agnostic search model using Arel

    In the last post, I explained how to make conditional searches based on conditional params. I wrote a very simple search model that returns a real model with query done by Arel. I refactored the code to make i simpler to use:

    The constructor takes the model you want to search in, and an hash of params to use, they’ll be the request params when used from controller. Note that if some param value is an empty string, it will be ignored: this lets the visitor to leave blank some fields in the search form and make it conditional.

    To save typings, when specifying conditions, you can omit the value, because it’s taken from the params hash. By the way, if you need some more control, you can specify another value. Finally, you can pass a block to make it easier to read. Here’s a real usage example from a controller:

    When Search#result is called a model instance is returned, it can still be ordered.

    According to Arel README, there’s no support for OR conditions yet, I hope it will be included soon.

    What do you think about?

  3. Rails3: using Arel to make conditional searches based on conditional params

    I needed simple searching on some models, and I didn’t want to use any plugin for this task, just because I’d like to try the new rails3 features, like ActiveRelation (Arel).

    I wrote a basic model called Search, I can re-use it for other models that need search features:

    Then I wrote a partial form with params, the following code is only an example, I have more fields:

    Finally the controller action called ‘search’. As you can see, the difficult part was that you don’t know which params are passed by the request, so you need to specify conditions only if they are present. Arel helped to resolve this problem:

    Probably it’s not the best solution, perhaps this could be optimized with some helper, but it works, and helps to figure out how Arel works.

    Webography:

  4. Basic user roles management (rails plugin)

    I’m working on a very basic Rails plugin to simplify management of user roles. It doesn’t cover authorizations (see @rbates’s cancan), just role names and values (read it as levels).

    
    class User < ActiveRecord::Base
      acts_as_authentic
      has_roleplay(:admin => 0, :teacher => 1, :student => 2)
    end

    With this, you can now check wich roles are avaiable (eg: calling User.roles) or check if an user has the right role (eg: @current_user.is_admin?).

    The code will be avaiable very soon on github, I have to write tests ;)