15 May 2014

Justify me this

for justification on one line

Oliver tells us about a special trick on css. This css code can spread distribution width without using table element. text-align: justify is used to let a block take full width of an element. But it’s not working when there only a line, so I use a pseudo-element :after to be a last fill line. Here is a sass example:

ul
      display: block
      text-align: justify
      line-height: 0
      li
        display: inline-block
      &:after
        content: ''
        display: inline-block
        width: 100%
15 May 2014

Eddie Vim and rcfiles

for rails devs

Mose sometimes uses vim on the side of ST3, and can’t do it without the pretty good eddie kao set of config files.

Check it out at https://github.com/kaochenlong/eddie-vim it’s tailored for rails dev. I gathered it (plus my oh-my-zsh setup) in my github rcfiles repo https://github.com/mose/rcfiles with an installer that I runs when I install a new server.

08 May 2014

zsh-syntax-highlighting

instant coloring in the console

This week AaronH shares some secrets of his configuration. You can check his whole config setup at https://github.com/aar0nTw/HomeConf but there is one special piece in that config.

If you use oh-my-zsh (and really, you should), clone https://github.com/zsh-users/zsh-syntax-highlighting in .oh-my-zsh/custom/plugins and add it in your .zshrc in the list of plugins=(). This will change color of your text if the command you type is not found.

As an extra tip, Aaron plugins list looks like:

plugins=(git rails ruby zsh-syntax-highlighting rake npm gem brew web-search rvm bundler tmux mux zeus github heroku colored-man copydir copyfile urltools themes postgres)
08 May 2014

View Objects

for a cleaner code in controllers

AaronK wants to detail a bit on what he learned about Models. it may be a bit long but hang on. Even we already know the patterns about how to refactor model from this article:

http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

Here’s a very useful concepts I learned when using view/form object patterns:

We should rather use the characteristic of encapsulation to place the related data into model (view/form object), rather than controller or view (template)

Background

Here’s a simple example of code we often use.

# in controller
    def edit
      @student = current_school.students.find(params[:id])
    end

    def update
      @student = current_school.students.find(params[:id])
      if @student.update_attributes(student_params)
        redirect_to student_path(@student)
      else
        render :edit
      end
    end

    # in students/edit.html.erb
    render 'form'

    # in students/_form.html.erb
    <%= simple_form for(@student) do |f| %>
      <%= f.input :first_name %>
      <%= f.submit %>
    <% end %>

The problem is…

One day, the student form needs some extra options, ex: grades. Another developer was asked to patch this requirement, who may add the data to:

def edit
      @student = current_school.students.find(params[:id])
      @grades = current_school.grades.enabled
    end

    Then put the options into the form partial file
    <%= simple_form for(@student) do |f| %>
      <%= f.input :first_name %>
      <%= f.input :grade_id, :collection => @grades %>
      <%= f.submit %>
    <% end %>

Everything seems going right, user can edit student with grades happily.

But often we miss the bad case. When saving failed, the update action would go to render edit view, but the form partial wasn’t allocated instance variable of @grades, and boom, it causes a server error. Unfortunately, it’s hard to track where a partial is used in what controller method.

How we avoid it by using FormObject

Thats why we need to use form object, we should encapsulate the data into the object.

def edit
      student = current_school.students.find(params[:id])
      @form = StudentForm.new(student)
    end

    def update
      student = current_school.students.find(params[:id])
      @form = StudentForm.new(student)
      @form.attributes = student_params
      if @form.save
        redirect_to student_path(student)
      else
        render :edit
      end
    end

then we should put the grade options in StudentForm, such as

class StudentForm
      attr_reader :grade_options
      def initialize(student)
      @student = student
      @grade_options = student.school.grades.enabled
      end
    end

    # students/_form.html.erb
    <%= simple_form for(@form) do |f| %>
      <%= f.input :first_name %>
      <%= f.input :grade_id, :collection => @form.grade_options %>
      <%= f.submit %>
    <% end %>

Furthermore, we could make the object become renderable, just extend ActiveModel::Naming or use custom partial path by implementing the method ‘to_partial_path’, such as:

class StudentForm
      def to_partial_path
        'students/form'
      end
    end

    # in edit.html.erb
    <%= render @form %>

    # in students/_form.html.erb
    <%= simple_form for(form) do |f| %>
      <%= f.input :first_name %>
      <%= f.input :grade_id, :collection => form.grade_options %>
      <%= f.submit %>

      <%# notice: the 'form' became local variable. %>
    <% end %>

Then all the variables used in the partial should come from the form object.

Similar problem when generaly using partial

And it is a similar concept when using view object, many times we share the partial between views, but each one didn’t know what data along the partial be shared with. Often we update the partial for patching page A but beak Page B because that is used by a different controller (because we place the data at the action as instance variables!!)

Conclusion

  • One action, one model, no more instance variables except the major object under the action.
  • Treat the target we are rendering as a object, not just a view file.
  • AaronK should write more blog posts
08 May 2014

Vector clock

for conflict detection

Now brace, here is a piece of science from iHower. He’s implementing a conflict detection mechanism for the Message Bus.

The purpose is to prevent conflicting updates. For example: If a user updates a student name in MB, and another user update the same student’s birthday in IS at the same time (or MB’s update does not reflect to IS for any reason). Since message bus is asynchronous, it’s possible these two core messages will overwrite each other randomly if there is no conflict detection.

The algorithm iHower uses is vector clock http://en.wikipedia.org/wiki/Vector_clock which is the most common approach used by peer-to-peer distributed systems. A vectors clock for three nodes (MB/OA/IS) will be like { MB: 1, OA: 1, IS: 2 }.

Each time a node has an internal update, it updates its own counter, so an update at MB would change its clock to { MB: 2, OA: 1, IS: 2 }. Whenever two nodes sync, it will sync their vector clock too.

Based on the vector clock, we can tell if one clock is newer than another because the newer clock will have “ALL” its counters greater or equal then those in the older clock.

So { MB: 3, OA: 2, IS: 2 } is newer than { MB: 2, OA: 1, IS: 2 }, but { MB: 3, OA: 1, IS: 2 } and { MB: 2, OA: 1, IS: 3 } have write-write conflict.

Vector clocks can help us spot inconsistency, but doesn’t resolve them. This will be our next todo.

08 May 2014

tmuxinator

autolaunch all your stuff

ILake always use tmuxinator https://github.com/tmuxinator/tmuxinator to manage the services and tool he needs in a project. For example this is what he uses in isis

project_name: isis
project_root: ~/rails_app/faria_prj/isis
pre_window: rvm use ruby-2.1.1
windows:
  - editor:
  - console:
  - nothing:
  - logs: tail -f log/development.log
  - guard: guard
  - server: spring rails s -p 8888
  - zeus: zeus start
  - redis: redis-start
  - sidekiq: sidekiq

It will help start redis, sidekiq zeus, guard etc…

08 May 2014

tig

is a git GUI in the console

UA Team wants to share the info about tig - the cool command-line interface to git which you may find useful. We started to use it this week.

To install it: brew install tig (or apt-get install tig)

Then in your project directory type it: tig

The commits tree appears, where you can navigate it and see the individual commit changes, as well as do other geeky things :) Enjoy!

tig

08 May 2014

Dictionnary in sublimetext

for the dyslexics

Mose recently has been annoyed by his own typoes and has been looking for a way to fix it. This is actually pretty simple to cmd-shift-p and install a package called Dictionnaries. Then by hitting F6 you switch on and off the spellcheck highlighting. When you write a lot of documentation that is very helpful (and you want to write a lot of documentation, don’t you ?).

The spellcheck auto-highlight can be enabled for specific file extensions (like .md files) by adding

"spell_check": true

in preferences > Settings - more > Syntax specific - user (while having a markdown page open)

08 May 2014

Console log

but shorter because devs are lazy

Naiting use console.log very frequently, so he has some function when developing (in coffescript)

_console = (act, something) ->
  typeof console != 'undefined' &&
  typeof console[act] == 'function' &&
  console[act](something)
ll = (t) -> _console 'log', t
tt = (t) -> _console 'table', t
cc = -> _console 'clear'

That way rather that putting console.log "blah" he will just use ll "blah" and it will not fuckup IE if he forgets to remove it.

08 May 2014

Cloudup

a free droplr

Oliver tells us about Cloudup. Basically this is a free version droplr (up to 1,000 items or 200 GB). If you haven’t subscribed droplr, you can try this first. Check it at https://cloudup.com

Pro tip: When you get the Cloudup url like this -> https://cloudup.com/cvWnAWh1kiA Add a ‘+’ at the end (https://cloudup.com/cvWnAWh1kiA+) then you can get the pure source file without Cloudup’s web frame. (This tip works on droplr too).