論盡蛋
心で書く

Blog


Up coming changes of this site

Haha it is actually a little bit strange to disclose the details of the models here, especially the same site's own models XD"

Currently we have 3 different models for "articles": Post, Page and Entry (entry is inside portfolio).

However, (intentionally) these 3 models shares 99.99% (ok, actually not mathematically calculated) the same attributes and behaviours:

  • translatable title and content
  • URL slugging (with friendly_id gem)
  • published_at handling in admin panel
  • preview in frontend
  • tags, comments, sharing

and even the frontend interface for these 3 things are extremely similar.

Actually I do intentionally to make them the same. It is because I do feel they should be the same. And now I'm right.

And even worse (or better??), I now am adding two more models: board games and coupons. And I found they could have the completely the same things too.

So...is it worth to group them together?

Now board games and coupons are subclasses of CollectionItem, which have the same attributes as post and page.

However, Coupon have more attributes than that, e.g. expired_at. So There is a CouponInfo model having 1-to-1 relationship to Coupon model.

It's actually good for me. And so now I can do something I wanted to do:

Currently this great responsive theme is not designed by me (you may fork the originally version in here, which was designed for Octopress).

The theme is great. However I do want a self-designed theme for my own blog.

Now I think it is the time ;)

I would do these 3 steps to do so:

  1. existing data migration
    • remember the translated versions
    • entry has an extra homepage attribute (that means there should be an EntryInfo model)
  2. delete old tables (backing up the database is a common sense)
  3. change the existing model to subclass from collection item
  4. run test cases again to confirm working

Unknown Heroku pull not working

According to this article, we can use heroku pull to export data from heroku's db to local db.

(Pulling my blog's posts down for the test of changing markdown engine)

However, I am getting this error:

!    Taps Load Error: cannot load such file -- taps/operation
!    You may need to install or update the taps gem to use db commands.
!    On most systems this will be:
!
!    sudo gem install taps

OK, it asked me to install taps, so I ran gem install taps (without sudo intendedly).

Then I ran again heroku pull, now a slightly different error occurred:

!    Taps Load Error: cannot load such file -- sqlite3
!    You may need to install or update the taps gem to use db commands.
!    On most systems this will be:
!
!    sudo gem install taps

What? install taps again..? But you mentioned cannot load sqlite3. I didn't use sqlite3 in this project, maybe taps internally uses sqlite3? OK, I try to install sqlite3 with gem install sqlite3.

Finally heroku pull works.


My Apache + Pow.cx setup

I use Mac OS X, which have Apache2 installed by default. On the other hand, Pow.cx is great for running Rails apps locally (and with the new .xip.io for other computers to access).

So this is a post for myself, to jot down notes on how to set these up.

Basically just follow this wiki.

After following the above wiki (Running Pow with Apache), all things should be ready now.

To create a rails app

Given ~/Projects/rails-app.

When you create a symbolic link in the ~/.pow directory.

#!bash
cd ~/.pow
ln -s ~/Projects/rails-app

Then you should be able to visit the rails app through http://rails-app.dev.

Renaming ~/.pow/rails-app could change the domain name.

To create a php app

Given ~/Projects/php-app

When you do these two things:

  1. edit /etc/hosts to add a host (e.g. 127.0.0.1 php-app.local)
  2. edit /private/etc/apache2/extra/httpd-vhosts.conf to add your virtual host (or the conf file you use to add virtual hosts)

    DocumentRoot "/Users/PeterWong/Projects/php-app" ServerName php-app.local Options Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews AllowOverride All Order allow,deny Allow from all

Then you should be able to access the site through http://php-app.local.


Pull to refresh table view controller

Finally can pay my full attention to iOS development.

Basically this is a subclass of UITableViewController, which adds the functionality of pulling downward to refresh (or reload).

The following is the usage:

  1. Copy the files into your project:

    • PPPullToRefreshTableViewController.h
    • PPPullToRefreshTableViewController.m
    • pullToRefreshArrow.png
    • pullToRefreshArrow@2x.png
  2. your table view controller should inherit from PPPullToRefreshTableViewController (which is a UITableViewController subclass), instead of the original UITableViewController

    1. in YourTableViewController.h
      1. #import "PPPullToRefreshTableViewController.h"
      2. @interface YourTableViewController : PPPullToRefreshTableViewController
    2. override the following method:
      1. - (void) refreshing
        • you should call didRefresh inside this method in order to hide the refresh header view
    3. you may want to call willRefresh to start refreshing in code (this method by default shows the refresh header view, and calls refreshing automatically)
  3. In your build target's Link Binbary with Libraries section, add the QuartzCore.framework

You may clone the demo project, which is a Master-Detail application together with the PPPullToRefreshTableViewController source code, from here:

git clone git://github.com/peterwongpp/PPPullToRefreshTableViewController.git

The project's repository: PPPullToRefreshTableViewController

Any pull requests, discussions or issues are welcome!


Drop PostgreSQL database

Update:

If you are using Rails 4.x, please read this. Thank you Manuel Meurer for letting me know the following implementation applies to Rails 3.x only.

If you are using Rails 3.x, you may continue use the following patch.


Some of my projects uses PostgreSQL as my database. However, running rake db:drop always gives me the following error:

Couldn't drop PROJECT_NAME_development : #<ActiveRecord::StatementInvalid: PG::Error: ERROR:  database "PROJECT_NAME_development" is being accessed by other users
DETAIL:  There are 2 other session(s) using the database.
: DROP DATABASE IF EXISTS "PROJECT_NAME_development">

To resolve this problem, as hinted by the message about, is to stop all sessions using that database.

However, I just found (I think) better solution from this stackoverflow answer (which points to this gist).

It is to monkey patch the rake db:drop command. To do so, simply copy the code into lib/tasks/databases.rake and now rake db:drop is patched with this code which stops the connections.

The code is as follow:

#!ruby #{Rails.root}/lib/tasks/databases.rake
=begin
  Monkey Patch 
  activerecord-3.0.9/lib/active_record/railties/databases.rake
  clears obstinate stale PG session to get parallel_tests working
  also, PG user must be superuser to use these low level PG functions
=end
def drop_database(config)
  case config['adapter']
  when /mysql/
    ActiveRecord::Base.establish_connection(config)
    ActiveRecord::Base.connection.drop_database config['database']
  when /sqlite/
    require 'pathname'
    path = Pathname.new(config['database'])
    file = path.absolute? ? path.to_s : File.join(Rails.root, path)

    FileUtils.rm(file)
  when /postgresql/
    ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x|
      if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/
        ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})")
      end
    end
    ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
    ActiveRecord::Base.connection.drop_database config['database']
  end
end