Starting a new Rails 4 : V. Builing some quick versionned wiki pages rails 4, vestal_versions, wiki, delegate, maruku

Roadmap

So let start a project manager, and make a short TODO List :

Creating the Project model

Classical :

rails g scaffold projects name:string description:text date_create:date owner:references user:references status:string --no-stylesheets

rake db:migrate

In the models :

    class Project < ActiveRecord::Base
      belongs_to :user
      belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
    end

    class User < ActiveRecord::Base
      authenticates_with_sorcery!
     
      validates :password,                presence: true, confirmation: true, length: { minimum: 3}, :if => :password
      validates :email,                   presence: true, uniqueness: true
      validates :password_confirmation,   presence: true, :if => :password
      validates :username,                presence: true

      has_many :projects 
      has_many :owners, :class_name => 'Project', :foreign_key => 'owner_id'
    end
    

Some views adjustment : The Demeter Way

Same things already used by the users view (paginate, simple_form, … ) It’s not DRY for the moment but there some solution with generators for later notes :)

One interesting thing : in index view I want to show the owner name %td= project.owner.username, but it may be null some time. The easy way : %td= project.owner.try(:username) … Dirty somewhere no ?

TIP : Rails delegate

So checkout this page : http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/

Here, adding some delegate to the user class :

    class Project < ActiveRecord::Base

      belongs_to :user
      belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'

      delegate :username, :to => :owner, :prefix => true, :allow_nil => true
      delegate :username, :to => :user, :prefix => "author", :allow_nil => true

    end
    

And now in the show.html.haml , we can use (with possibly null value) :

  %p= @project.owner_username
  %p= @project.author_usermane

Wiki pages

Build the scaffold :

rails g scaffold wiki name:string content:text owner:references author:references status:string --no-stylesheets

As usual, adapt the view, the model and the controller … (check the source).

Wiki Editor

WYSIWYG HTML5 editor becomes usual over markup editor … Will check one in the future, but for now, I choose using Maruku.

Simple (dirty) WikiWords

    module WikisHelper

      def wiki_style(txt)
        txt.blank? ? '' : Maruku.new(wiki_words(txt)).to_html
      end

      def wiki_words(txt)
        txt.gsub /(\[\[.*?\]\])/ do |lk|
          link = lk[2..-3].gsub(/([A-Z]+|[A-Z][a-z])/){|x| ' ' + x }.strip
          exist = Wiki.where(:name => link).take
          if exist.blank?
            "[#{link} ?](/wikis/new)"
          else
            "[#{link}](/wikis/#{exist.id})"
          end
        end
      end

    end
    

and call it in view by = raw wiki_style @wiki.content

Versioning : PaperTrail or Vestal_versions …

I choose Vestal_versions, but both gems aren’t ready for Rails 4.

So clone the Github, checkout a new branch, and let’s work on it, with a little tips :

TIP : a gem pointing to a local git repository

Take from http://gembundler.com/v1.3/git.html, ie here :

git clone https://github.com/laserlemon/vestal_versions.git
git checkout -b 'rails-4'
bundle config local.vestal_versions /c/my_local_git_dir/vestal_versions/

and in gemfile :

gem 'vestal_versions', :github => ' laserlemon/vestal_versions', :branch => 'rails-4'

You can visualize the presence of the git branch with just a bundle show

Vestal_version : installation and usage

First, in your local git branch of vestal, remove all the gems dependencies you can find (and check the result with bundle check).

Run the migration generator :

rails g vestal_versions:migration
rails db:migrate

Add the declaration to the model models/wiki.rb : versioned. Now have to track incompatibility with Rails 4 …

For the views, I used http://asciicasts.com/episodes/177-model-versioning : views/wikis/show.html.haml :

    ...
    - @wiki.versions.each do |v|
      = link_to v.number-1, :version => v.number-1
    ...
    

and in the controller :

    def show
      @wiki.revert_to(params[:version].to_i) if params[:version] 
    end
    

I’ve put for the moment a quick link to a wiki page created when a new project is created.


comments powered by Disqus