Namespace vs. Scope

I’ve often asked myself what exactly the difference between namespace and scope is.

Namespace

This is the simple option. It will prefix the generated path and the path name. And it also assumes that the controller is to be found under a module named in the same manner as the namespace itself.

namespace :management do
  resources :users
end

Generated routes:

Prefix Verb      URI Pattern                            Controller#Action
management_users GET    /management/users(.:format)     management/users#index
                 POST   /management/users(.:format)     management/users#create
management_user  GET    /management/users/:id(.:format) management/users#show
                 PATCH  /management/users/:id(.:format) management/users#update
                 PUT    /management/users/:id(.:format) management/users#update
                 DELETE /management/users/:id(.:format) management/users#destroy

Scope

Scope can give you a more accurate result but is a bit more complex at the same time.

Without options

When using scope without any options and only a scope name, it will just add a prefix for the generated path.

scope :management do
  resources :users
end

Prefix Verb   URI Pattern                Controller#Action
 users GET    /management/users(.:format)     users#index
       POST   /management/users(.:format)     users#create
  user GET    /management/users/:id(.:format) users#show
       PATCH  /management/users/:id(.:format) users#update
       PUT    /management/users/:id(.:format) users#update
       DELETE /management/users/:id(.:format) users#destroy

With option: module

“module” lets you define another module and only the module.

scope module: 'management' do
  resources :users
end  

Prefix Verb   URI Pattern          Controller#Action
 users GET    /users(.:format)     management/users#index
       POST   /users(.:format)     management/users#create
  user GET    /users/:id(.:format) management/users#show
       PATCH  /users/:id(.:format) management/users#update
       PUT    /users/:id(.:format) management/users#update
       DELETE /users/:id(.:format) management/users#destroy

With option: path

“path” will prefix the generated path

scope module: 'management', path: 'fu' do
  resources :users
end

Prefix Verb   URI Pattern             Controller#Action
 users GET    /fu/users(.:format)     management/users#index
       POST   /fu/users(.:format)     management/users#create
  user GET    /fu/users/:id(.:format) management/users#show
       PATCH  /fu/users/:id(.:format) management/users#update
       PUT    /fu/users/:id(.:format) management/users#update
       DELETE /fu/users/:id(.:format) management/users#destroy

With option: as

“as” can be used to change the name of the path method used to identify the resources.

scope module: 'management', path: 'fu', as: 'awesome' do
  resources :users
end   

Prefix Verb   URI Pattern                    Controller#Action
awesome_users GET    /fu/users(.:format)     management/users#index
              POST   /fu/users(.:format)     management/users#create
awesome_user  GET    /fu/users/:id(.:format) management/users#show
              PATCH  /fu/users/:id(.:format) management/users#update
              PUT    /fu/users/:id(.:format) management/users#update
              DELETE /fu/users/:id(.:format) management/users#destroy

Handle simple remote modal dialogs in rails applications

I will show you how to handle simple remote modal dialog rendering in rails apps.

Sometimes we do not want to write big javascript applications to have working remote modals in our rails applications. And rendering modals on the client is to bit of a hassle? Why not let the server (fastest html renderer in town) respond with complete dialogs?

Iam using Bootstrap Modals for this example. But it will work for any JS modal library.

Step 1 – Add a new modal layout.

<!-- app/views/layouts/modal.html.erb -->
<div class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">
      <%= yield %>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

We also need to define a place where the dialogs will be rendered. Add the following to the application layout file.

<!-- app/views/layouts/application.html.erb -->
<div id="modal-holder"></div>

Step 2 – Add modal javascript

This will enable links with data-behavior=”modal” attribute to be rendered in modal windows.

$ ->
  modal_holder_selector = "#modal-holder"

  $(document).on "click", "[data-behavior='modal']", ->
    $('body').modalmanager('loading')
    location = $(this).attr("href")
    $.get location, (data)->
      $(modal_holder_selector).html(data).find(".modal").modal("show")
    false

  $(document).on "ajax:success", "[data-behavior='modal-form']", (event, data, status, xhr) ->
    # make sure this event is observered by document and not by dom node itself.
    url = xhr.getResponseHeader("Location")
    # Navigates to given location header in http response or closes the modal handler.
    if url
      window.location = url
    else
      # FUTURE TODO: make sure only the modal which was called last will be destroyed.
      $(".modal").modal("hide")
    false

Step 3 – Modify controller action

Now change the render layout for the controller action like so:

class ApplesController < ApplicationController
  def new
    @apples = Apple
    render layout: 'modal'
  end
end

Step 4 – Use it

<%= link_to 'Create apple', new_apple_path, data: { behavior: 'modal' } %>

Please make sure the rendered form will have a data-behavior=”modal-form” attribute to successfully close the dialog after valid ajax response.

BEM! Tackle your growing CSS with a Pattern that just works

As i worked on a big project for my job, we came to the conclusion, that just using the Twitter Bootstrap CSS Framework with some view specific CSS code is not enough.

This all resulted in some big assets folders with a huge load of files which prevented any kind of good maintainability. BEM, meaning Block, Element, Modifier, is a front-end methodology developed at Yandex.

It is important to note that the naming techniques covered in this post are not the original BEM ones, but are altered versions that I much prefer. Whatever actual notation is used, they are all based on the same BEM principles.

.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
.long_block_name {}

There are basically three groups:

  • .block: the root block component
  • .block__element: a part of a block component
  • .block--modifier: a variant, modification, extension of a component block (can also be aplied to an element)

Elements are delimited by two underscores. Modifiers are delimited by 2 hyphens. Long block names are delimited by one underscore. This has the advantage that you can select the classes better by a double click.

The whole point is to improve readability by other developers, so you can tell what the markup is doing by the name alone.

Let me give an example. You probably all know the .media element from different kinds of CSS Frameworks.

.media {}
.media__img {}
.media__img--right {}
.media__body {}

<div class="media">
  <img src="image.png" class="media__img media__img--right" alt="awesome image"/>
  <div class="media__body">
    <h2><!-- title --></h2>
    <p class="lead"><!-- some lead text --></p>
  </div>
</div>

Now we can see, that .media is a block and .media__img is a element with a modification or extension .media__img--right. The class .lead has nothing to do with our component. This is very helpful.

Rails: Time, DateTime, Timezones…. wait, what?

Everything happens in UTC!
Thats the one basic thing you must know about handling Times in Rails.

SomeModel.create(:time_attribute => Time.now)
SomeModel.create(:time_attribute => Time.zone.now)

Both lines will insert the same value into the database –> UTC+0. ActiveRecord will automaticly convert the given time. Therefore the config.time_zone in application.rb only controlls the default timezone and not the Timezone format the database will store the attribute.

You can also safely compare times that are in different zones – you don’t need to convert them to some common timezone.

A good link I found while adding time zones to our own project was this: http://www.redguava.com.au/2010/12/rails-basics-handling-user-timezones-in-rails/

Collapsible CSS3 paper cards, inspired by Google Material Design

I`m a big fan of the Google Material Design. In particular, the paper card accordion. So I made one myself.

paper-collapse

Demo

Feel free to fork me on Github.

<div class="collapse-card">
  <div class="title">
    <i class="fa fa-question-circle fa-2x fa-fw"></i>
    <span>
      <!-- Optional right aligned text -->
    </span>
    <strong>
      <!-- Title Text -->
    </strong>
  </div>
  <div class="body">
    <!-- Body Text -->
  </div>
</div>