Comparison of Rails and Dancer2


The goal is to provide a somewhat useful comparison between the two frameworks and languages. G. Wade Johnson picked a relatively simple application (a blog), but decided not to build the simplest implementation. The presentation would walk through most of the steps of construction somewhat live, to give a feel for the tooling. The changes are in a git repo, so we don't need to write all of the code live.

Rails has a little advantage in both the type of project and the tooling, since a blog is one of the standard Rails apps. By working for a solution that is not quite the obvious one, we get a better comparison. Use plugins as possible to simplify implementation (which is also what you would do if you were actually solving this problem). This serves to compare the plugin features of the two frameworks.

We will use a single SQLite3 database for both applications. This forces the models to be the same. It also means we don't need to do database design and creation twice, since the database is not what we are focusing on.

Data Model

Will Provide

The goal is to be complicated enough to be interesting, but not so complication that we can't finish. We also want to make the project a little different than the default Rails app, to make the comparison somewhat realistic.

Will Not Provide

There were a lot of features that could make this more like a real CMS. More features were unnecessary for the goal of comparing the two frameworks.

Rails Implementation

The repo for this project is available.

We will use the rails tool to construct pieces of the application. In particular, we use the rails tool to build tables. We'll rely on a small number of gems (libraries) for some needed functionality.

Steps in the exercise

  1. Create the project:
    rails new --skip-keeps --skip-puma --skip-coffee {app_name}
    • Add to Gemfile in :development
      • rspec
      • rspec-rails
      • pry-byebug
    • bundle install
    • Remove test directory
  2. Create User model:
    rails g model user uuid:string:uniq userid:string:uniq name:string password:digest
  3. Create Blog model:
    rails g model blog uuid:string:uniq title:string description:string user:references
  4. Creare Post model:
    rails g model post uuid:string:uniq title:string content:string blog:references
  5. Update models
    • Blog: add has_many :posts
    • User add has_many :blogs
  6. Add tag models
    • rails g model tag name:string
    • rails g model post_tag post:references tag:references
  7. Actually generate tables:
    rake db:migrate
  8. Add to Gemfile
    • Uncomment bcrypt
  9. Update dependencies:
    bundle update
  10. Set up use of rspec test system:
    rails g rspec:install
  11. Add User definitions to db/seeds.db file
    • Modify models to auto set uuid
  12. Build model tests
  13. Remove coffee-rails from Gemfile:
    bundle update
  14. Create main controller:
    rails g controller Blogs
    • Update config/routes.rb
    • rake routes
  15. Create a view: app/views/blogs/index.erb
    • Fill it out
    • Update Blog#index with list of blogs
  16. needed show.erb, new.erb, and create.erb as well
    • Update controller methods to support
  17. rails server - to demonstrate
  18. Add devise gem to do authentication
    • Update Gemfile:
      bundle update
      rails g devise:install
    • modify app/views/layouts/application.html.erb
      rails g devise user
      rails db:migrate
    • Deleted database because of constraint fail.
    • Updated seed file
      rails db:migrate
    • Remove the `has_secure_password` item in user model
      rails db:seed
    • Tear out old auth setup
    • Finish connecting in devise
    • Disconnect authentication from index and show
    • Add blog editing
      • Create edit form
      • Update blog actions for edit and update
      • cleanup
      • Update blog controller specs
    • Add posts
      • rails g controller posts
      • Build templates
      • Update controller methods
      • Add edit icon and deal with asset/public issue
    • Add markdown support
      • Filter any HTML to make it safe
      • Convert markdown into the correct form.
    • Attempted to protect the edit button on show blog or post
      • Only check owner if we have a current_user
      • current_user is only set if we authenticate
      • if we authenticate, must be logged in to see post/blog
      • Suggestion on line was to use guest user
        • Page of new code to create/maintain guest users
        • Guest users live in user table.
        • Requires patching session code
    • Use bootstrap to improve styling
    • Fix the show issue

To complete the project, I would want to work out how to make the asset pipeline work correctly. That is supposed generate, minimize, etc. static files. I also need to expand the testing dramatically.

Dancer2 Implementation

The repo for this project is available.

Database models will need to be built by hand. If we were generating tables, they would be done manually. We'll rely on a small number of modules (libraries) for some needed functionality.

Steps in the exercise

  1. Create project:
    dancer2 gen -a dancer_blog
  2. Add dependencies to Makefile.PL
    • Dancer2::Plugin::Auth::Extensible
    • DBIx::Class
    • Template::Toolkit
    • DBD::SQLite
    • Text::MultiMarkdown
    • Plack
    • Plack::Middleware::Deflater
  3. Update configuration
    • config.yml
      • enable template_toolkit template engine
      • enable Simple session engine
    • environments/development.yml
      • set logger to file
      • turn off errors
  4. Make database models
    • Blog
    • Post
    • User
  5. Add blog controller
    • Add index and show routes
    • Create templates for index and show
    • Build controller actions for index and show
    • Create Paths file for DRY path definitions
    • Add new/create routes, template, and actions
    • Add edit/update routes, template, and actions
  6. Add authentication support
    • Login/logout
    • Restrict access to create/edit blog capabilities
    • No login requirement for show or index
      • Check logged in user on show to decide whether edit allowed
  7. Add post controller
    • Add show route, template, and controller action
    • Add new/create routes, template, and controller actions
    • Correct blog code pointing to posts
    • Add edit/update routes, template, and actions
  8. Markdown functionality
    • Markdown on output
    • Scrub HTML before saving to database and after
  9. Add bootstrap
    • Add bootstrap library
    • Reformat templates to use bootstrap
    • Modify style.css to tweak look.
  10. Fix login redirect
    • Display the user name if logged in
    • Pass the login url to each template instance
    • Modify the login url with the return_url if supplied
  11. Make CSRF protection work
    • Replace broken plugin with new code
    • Incorporate new code

To complete the project, I would modify for https and secure cookie support. I would add full validation to all parameters. I would also add much more testing code.


We had 9 people attending this month. As always, we'd like to thank HostGator, LLC for providing the meeting space and food for the group.