04 June 2014

Media queries from scratch

because small is beautiful

This is a small snippets set for media queries, if you don’t want to learn/use a framework like sussy or breakpoint, you may like this

body
  background: red
  +tablet
    background: green
  +desktop
    background: blue

mixin below

$mobile: 480px
$tablet: 1024px

=min( $min )
  @media (min-width: $min + 1)
    @content

=max( $max )
  @media (max-width: $max)
    @content

=between( $min, $max )
  @media (min-width: $min + 1) and (max-width: $max)
    @content

=mq($device)
  @if $device == mobile // 0 ~ $mobile
    +max($mobile)
      @content
  @else if $device == desktop // $tablet ~ 
    +min($tablet)
      @content
  @else if $device == not-mobile // $mobile ~ 
    +min($mobile)
      @content
  @else if $device == tablet // $mobile ~ $tablet
    +between($mobile, $tablet)
      @content

// create your own aliases
=tablet
  +mq(tablet)
    @content
=desktop
  +mq(desktop)
    @content
=mobile
  +mq(mobile)
    @content
=not-mobile
  +mq(not-mobile)
    @content
04 June 2014

Vim leader key

from outer space

In my .vimrc there is an important line

let mapleader = "\<Space>"

This is a tiny trick but it is very helpful for me. Recently I changed my leader key to <space>. I was using \, before. Now I can reach the leader key by both hand :p Much more convenient.

04 June 2014

Make a gem

it's simpler than what it looks

Making and publishing your own gems is so incredibly simple. Here is my setp by step process when I want to publish one:

Make a Rubygems account

curl -u username https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
  Enter host password for user 'username':

  chmod 0600 ~/.gem/credentials

Prepare the code

These steps are my typical path, nothing is really mandatory there.

  • create a repo at github (or wherever you want)
  • create a base gem skeleton bundle gem mycoolgem
  • update the README.md, add some minimal information. The clearest you explain what it does the best chances people will adopt it. Add cypirght information
  • create a CHANGELOG.md because when you publish something you need a clear log of your version changes
  • enable the tracking on codeclimate, travis, coveralls, gemnasium
  • add badges from http://shields.io in the README.md because it helps to qualify the state of the code quickly
  • when the gem code don’t need to have access to the version number, I found convenient to just remove the version file and add version in the .gemspec from the changelog file with spec.version = File.read(File.expand_path('../CHANGELOG.md', __FILE__))[/([0-9]+\.[0-9]+\.[0-9]+)/] (so then when I version bump there is only one file to edit)
  • write the code (or copy it from the private app you extract it from)
  • add a spec/ or test/ dir and write some tests and try to reach a decent coverage

Release it

  • add the date in the changelog for the current version
  • rake release
  • bump the version to the next increment in the changelog (and version file if any)

Overall with the initial bundle command and the final rake task for release, it’s pretty straightforward.

Also check http://guides.rubygems.org/make-your-own-gem/

04 June 2014

Restore user data

from a mysql db

Lets say you accidentally delete a user and want to put him back. I will go grab a db backup and intentionally delete this user to get the related deletion sql log (on all associated tables). Copy those log and do (because on mac)

pbpaste | grep DELETE FROM

We will get the related sql. Import the backup again and go Query in the Sequel Pro. Reverse the delete sql to select. For example, if we have

SQL (0.4ms)  DELETE FROM `field_string_values` WHERE `field_string_values`.`id` = 1054006
SQL (0.4ms)  DELETE FROM `field_string_values` WHERE `field_string_values`.`id` = 1062308

Then the select sql should be:

SELECT `field_string_values `.* from `field_string_values ` WHERE `field_string_values `.`id` IN (1062308, 1054006);

In the lower window we will get the query result. Right click and select COPY as SQL inset and paste it in the mysql console then you are done! Keep doing this till all DELETE is restore. Then you have the student back.

28 May 2014

Track dirty attributes

from an arbitrary model

ActiveRecord::Dirty feature provides a way to track changes in your object. But how do we add support for an arbitrary attribute?

For example in KB, organization’s custom data (i.e. MB/OA/iSIS subdomains) does not belong to Organization model, it belongs to another custom FieldStringValue model. And I want to have Organization#custom_fields_changed?, Organization.changes… etc “dirty” methods.

The key Rails API is attribute_will_change!(attr). If custom fields are changed, it will call attribute_will_change!(‘custom_fields’) that tell Rails.

28 May 2014

Codemirror

a browser code editor

When I implemented the template design for a tokenized message, I found CodeMirror.js very useful.

http://codemirror.net

It can help to easily create code highlight and formatting.

28 May 2014

Benchmarking in rails

and manipulate the returned values

This week I have to do some benchmarking and I found out rails provides a library which can help accomplish it easily.

http://apidock.com/rails/ActiveSupport/Benchmarkable/benchmark

Refer to the example code, which can do benchmark for the given process and write into log file.

But my requirements is to get the benchmarks and do some extra calculation. So I read the source code and finally I did something like:

milliseconds = Benchmark.ms do
   ........
end

It will return the time taken by the process, then I can do anything I want with it.

28 May 2014

Git last branch

a trick to type less

Here is a small trick for git. The dash (or hyphen) - is an alias for the last branch used.

You can use it to save time like this:

$[develop] git checkout release
$[release] git merge - # Will merge develop to release branch
$[release] git checkout - # Checkout to develop
$[develop]
28 May 2014

Four fingers swipe

and more crazy gestures

Have a look at

Used in conjunction, a MacBook user can assign four-finger swipe gestures to re-tile windows quickly. BetterTouchTool is capable of binding arbitrary gestures to arbitrary actions.

28 May 2014

Prince PDF in view object

with a doubt ...

The princely gem (from princexml) is convenient to generate pdf out of a controller, because we have a view object and I want the pdf generation to bind to it.

# lib/princely_pdf.rb
module PrincelyPdf
  extend ActiveSupport::Concern

  included do
    include ActionController::Rendering
    include Princely::PdfHelper
    include Princely::AssetSupport
  end

  def build_pdf_data(options = {})
    options = {
      :stylesheets => [],
      :layout => false,
      :relative_paths => true,
      :server_flag => true
    }.merge(options)

    prince = Princely::Pdf.new(options.slice(:server_flag))
    # Sets style sheets on PDF renderer
    prince.add_style_sheets(*options[:stylesheets].collect{|style| asset_file_path(style)})

    html_string = render_to_string(options.slice(:template, :layout, :handlers, :formats))

    html_string = localize_html_string(html_string, Rails.public_path) if options[:relative_paths]

    prince.pdf_from_string(html_string)
  end

  def pdf_file(options = {})
    @pdf_file ||= begin
                    options[:pdf_file_data] ||= build_pdf_data(options).force_encoding('utf-8')
                    options[:filename] ||= "report"

                    report_temp_file = Tempfile.new([ options[:filename], '.pdf' ])
                    report_temp_file.write(options[:pdf_file_data])
                    report_temp_file.rewind
                    report_temp_file
                  end
  end

  def render_to_string(options = {})
    raise 'overwrite me'
  end
end
# view object
require 'princely_pdf'

class StudentTranscript
  include PrincelyPdf

  def render_to_string(options = {})
    av = ActionView::Base.new(ActionController::Base.view_paths)
    av.extend TranslationHelper
    av.render(:template => "contacts/transcripts/index.pdf.erb",
              :layout => options[:layout],
              :locals => {
                          :@school => SchoolDecorator.new(school),
                          :@student => StudentProfilePresenter.new(student)
                         })
  end
end

But I feel bad smell here, because we just use the template in this view object, that is fine. But if we need this template both from view object and controller, that may violate the DRY policy. I feed that it could be dangerous, because you probably can forget to add some variables in the other place, Anyone have better idea ? (send to devtips at faria.co)