August 23, 2012 #rails

Yesterday I upgraded one of my old-pending-hobby projects to latest Rails version, which is 3.2.8 now. Since I have several other projects in old version, I'd like to keep a note for what I've done.

As you can see in my commit, all you have to do is update the version in Gemfile and hit bundle update in your terminal.

```ruby Gemfile
gem 'rails', '3.2.0'

group :assets do
gem 'sass-rails', " ~> 3.2.3"
gem 'coffee-rails', "~> 3.2.1"
gem 'uglifier', '>= 1.0.3'
end


Then add new configuration to `development.rb` and `test.rb` environment file. That's all :)

```ruby config/environments/development.rb
  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL)
  config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Do not compress assets
  config.assets.compress = false

```diff config/environments/test.rb

  • # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets
  • config.assets.allow_debugging = true

  • # Raise exception on mass assignment protection for Active Record models

  • config.active_record.mass_assignment_sanitizer = :strict

August 14, 2012 #rails

The order may different

Suppose you're retrieving records using array of ids.

ids = [100, 1, 6]
User.where(:id => ids).map(&:id)
# => [1, 6, 100]

The order of the data may different from ids array, what if you want to keep its order?

for MySQL

There is a function in mysql called FIELD()

FIELD(str,str1,str2,str3,...)
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.

So by combing this FIELD() function, here is the code.

ids = [100, 1, 6]
User.where(:id => ids).order("field(id, #{ids.join(',')})").map(&:id)
# => [100, 1, 6]

This will generate SQL below:

SELECT `users`.* FROM `users` WHERE `users`.`id` IN (100, 1, 6) ORDER BY field(id, 100, 1, 6)

for other databases

I didn't dig too much but most of google results suggest sort it manually using ruby.
Here is an example:

ids = [100, 1, 6]
users = User.where(:id => ids)
users = ids.map {|id| users.detect {|user| user.id == id } }
users.map(&:id)
# => [100, 1, 6]
August 3, 2012 #chrome

cmd + 0 in mac :)

If you click the tool icon on the right of the address bar, you can also check the current zoom rate.

'Google Chrome Check Zoom Rate'

July 20, 2012 #zsh

oh-my-zsh is very handy and I've been using it for almost a year.

But I found the auto correct is kind of annoying and barely helped me. So I decided to turn if off!

Disable it globally

Add this unsetopt to your ~/.zshrc

source $ZSH/oh-my-zsh.sh

unsetopt correct_all

Disable it per command base

Say if you just want to disable it for git command, you can setup an alias.

alias git=’nocorrect heroku’

I didn't test out this one :)

References:

July 20, 2012 #machinist rspec test

CAUTION It's specific machinist 1.0-maintenance.

Machinist is an alternative for Fixtures or FactoryGirl.

make_unsaved

If you want to generate an object without saving it to the database, replace make with make_unsaved

reference

So remember to use make_unsaved.

More

If you're interested, here is the source code.

Under latest version

Well if you're using latest machinist, which is 2.0 at this point, it's much simpler and cleaner.

make for generating but not saving an object, make! for saving it to database.

July 8, 2012 #zsh #octopress

Square brackets in zsh

Square brackets in zsh have special meanings but in MOST circumstances maybe you just have to escape them by putting \(backslash) before them.

Here is a example for generating a new octopress post

rake new_post["Escape square bracket by default in zsh"]
zsh: no matches found: new_post[Escape square bracket by default in zsh]

rake new_post\["Escape square bracket by default in zsh"\]
mkdir -p source/_posts
Creating new post: source/_posts/2012-07-08-escape-square-bracket-by-default-in-zsh.markdown

How to escape by default?

Just setup this alias in your .zshrc.

alias rake='noglob rake'
June 29, 2012 #rails #script

Overview

If you wanna execute some ruby code in rails environment, say manipulate w/ model or something, you can always try rake task first. But there're circumstances you don't want to use it, maybe it's just a one-time script that you don't want to save it to git, or whatever.

I've found out there're two simple ways to accomplish it.

require config/environment.rb

# test.rb
require "config/environment"
p User.first

# in terminal
ruby test.rb

use rails runner

Rails Guides about rails runner

runner runs Ruby code in the context of Rails non-interactively. For instance:

rails runner "p User.first"
rails runner some_ruby_script.rb
rails runner -e staging "Model.long_running_method"
rails runner -h

You can also use the alias “r” to invoke the runner: rails r.

I failed to call rails r on Rails 3.0.10, maybe it's above 3.1+.

June 29, 2012 #rails

I was wondering why people explicitly specify table name in such a scope definition...

class Answer < ActiveRecord::Base
  scope :recent, order('answers.created_at DESC')
end

Until I got this error today.

Mysql2::Error: Column 'created_at' in order clause is ambiguous: SELECT  COUNT(DISTINCT `answers`.`id`) AS count_id, question_id AS question_id FROM `answers` LEFT OUTER JOIN `questions` ON `questions`.`id` = `answers`.`question_id` WHERE (`answers`.user_id = 87) GROUP BY question_id ORDER BY created_at DESC LIMIT 10

I have a recent scope defined in both Question and Answer model. And when you chain those two models, rails don't know the recent is associated to which one.

@answers = @user.answers.recent.group(:question_id).includes(:question).limit(10)

Goal

To use facebook comments integrated to your own site.

Requirements

Need a facebook application for your site(domain).

For example:

How to get it

Fill in the blank and click get code from https://developers.facebook.com/docs/reference/plugins/comments/

Then just paste that code to your site(page).

Functions

  • People who want to comment can choose if post to Facebook, there’s a checkbox.
  • Comments posted to facebook are bidirectional. Threads stay synced across Facebook and on the Comments Box on your site regardless of where the comment was made.
  • Sort comments by Social Ranking, Chronological(Time) order
  • Boosting comments: Moderators can now ensure that high-quality comments appear at the top of the Comments Box

Facebook doesn’t explain how the Social Ranking works, but I checked some real-world examples and I guess basically we can consider it sort by like counts.

Moderation Tools

Put this meta tag in the html.

<meta property="fb:admins" content="{YOUR_FACEBOOK_USER_ID}" />

Then if you log in with the owner of the application, you can access this url to control comments:

http://developers.facebook.com/tools/comments

or you can do it inside the Comments Box directly.

There’re Moderate dropdown to Hide comment, Ban User or Boost comment. In the Settings page you have other options like add moderators or set blacklisted words, etc.

Remember to check all the FAQ on the reference docs, very useful. I wonder why those go to the FAQ though.

Reference

https://developers.facebook.com/docs/reference/plugins/comments/