2012年11月17日 星期六

[宅] 在Ubuntu安裝PostgreSQL

之前的環境是在windows,現在開始要慢慢搬到Ubuntu上,但是在安裝的過程中碰到了一點麻煩,在這邊做一個筆記,希望有相同問題的人或自己以後能更順利。

Install PostgreSQL 

安裝的過程很簡單沒有什麼問題,但是不知道為什麼9.1版在我的電腦跑不起來,所以改裝8.4
sudo apt-get install postgresql-8.4


啟動PostgreSQL

sudo /etc/init.d/postgresql-8.4 start
如果不行的話把版本去掉
sudo /etc/init.d/postgresql start

其他postgredsql操作:
sudo /etc/init.d/postgresql stop
sudo /etc/init.d/postgresql restart
sudo /etc/init.d/postgresql reload


設定database

對於postgresql的相關操作都是在psql這個postgresql的shell底下做的,但是一般使用者的權限不能執行他,就算你加了sudo也是一樣,所以這時候我們要切換到postgres在安裝過程中為我們建立的使用者"postgres":
sudo su postgres
接著我們就會看到shell的輸入欄位變成這樣:postgres@yourhost:
然後就可以開心的進入psql囉~
首先我們先來看看目前的使用者有誰,輸入"\du",會出現以下的畫面:

首先就是修改postgre這個superuser的密碼
ALTER USER postgres WITH PASSWORD ' <***password***> ';

要注意的是,在psql內下的SQL指令的結尾,要加上分號";"後才會執行,所以你也可以分成好幾行來打,最後一行加上分號再按ENTER就會執行了。
postgres=# SELECT *
postgres-# FROM BOOKS;


重要SQL指令

到了這邊大概都沒啥問題了,只剩一些Database和table的設定罷了。


  • 建立資料庫 CREATE DATABASE <dbname>
  • 建立資料表 CREATE TABLE <tablename>(COLUMN …)
  • 刪除資料庫 DROP DATABASE <dbname>
  • 刪除資料表 DROP TABLE <tablename>
  • 修改資料表 ALTER TABLE <tablename> …
  • 修改使用者 ALTER USER <user> WITH …


要查詢更細的設定只要在"\h"之後加上指令即可

2012年11月14日 星期三

[宅] javascript筆記 - window.location類別

window.location是個非常好用的物件,除了可以跳轉外,他還提供了很多讀取所在網址的相關資訊。我們先來看看"http://cat-son.blogspot.tw?foo=bar#a"這個頁面的window.location的attributes:

assign: function () { [native code] } //跳轉
hash: "#a" //取得錨點
host: "cat-son.blogspot.tw"
hostname: "cat-son.blogspot.tw"
href: "http://cat-son.blogspot.tw/#a"
origin: "http://cat-son.blogspot.tw"
pathname: "/"
port: ""
protocol: "http:"
reload: function () { [native code] }
replace: function () { [native code] }
search: "?foo=bar" //網址後的query值>

頁面跳轉

可以用以下幾種方法直接修改window.location的值:
window.location="http://example.com";
window.location.href="http://example.com";
location="http://example.com";
location.href="http://example.com";
或是使用window.location所提供的function來跳轉:
window.location.assign("http://example.com");
window.location.replace("http://example.com");
assign()和replace()效果差不多,差別在於replace是置換掉現在的document,不會留下被置換掉的頁面紀錄,所以當你按下"上一頁"時回到的其實是你"上上個"看到的頁面....
這樣講一定聽不懂,舉個例來說好了:

當我從A頁面逛到B頁面後,在B頁面執行了location.replace(C頁面),會把當前的document從B換成C,所以當我點上一頁時就是回到A。示意:
A-->B
↓
location.replace(C)
↓
A-->C
而使用location.assign則會是這樣的情況:
A-->B
↓
location.assign(C)
↓
A-->B-->C
所以在C頁面點上一頁會回到B而不是A


取得資訊

很多時候我們使用get這種方式來傳遞資料時,傳遞的資料會出現在網址後端,這時我們就可以從window.location.search這個字串拿到query值。例如在"http://example.com/?foo=bar"的頁面下,我們的window.location.search就會是"?foo=bar"
window.location.hash則是achor的值,也就是錨點。
但要注意的是,網址中只要在"#"之後的字串都會被視為hash,所以當你要同時傳遞anchor和query時,務必要把anchor放在最後面,例如:
"http://cat-son.blogspot.tw?foo=bar#a"


重讀頁面

使用window.location.reload(forceGet)
forceGet是個布林值,預設為false,代表只要從cache中重新載入就好,不需要再向server做http request;反之為true時,代表一定要再向server重新要資料。
這個特性還滿重要的,可以避免重讀時拿到舊資料,同樣的目的可以透過加上隨機的query值來達成。


小補充

關於document.location和window.location的差別:
window.location is read/write on all compliant browsers.
document.location is read-only in Internet Explorer (at least), but read/write in Gecko-based browsers (Firefox, SeaMonkey).




2012年11月10日 星期六

[宅] node.js KO Hackthon初體驗

現在是晚上將近11點,小弟的TEAM還在做很廢的功能.....XD
好啦,不說廢話認真作筆記:

MongoDB

之前一直沒有好好鑽研他,直到今天實在是沒法度了(MySQL哭哭),臨時抱佛腳開始使用MongoDB(這個決定好像也是晚上10點決定的Orz)。

下次參加Hackthon要先做功課啊啊啊啊

MongoDB其實是不太需要"建立"所謂的資料庫的,當你需要一個新的資料庫,概念上像是javascript中創建一個object一樣。預設好像是使用test,讓我們來新創一個db object:
> use myDB
switched to db myDB
來看看現在是使用哪個DB呢
> db
myDB
good~然後我們要連到DB時大概像是這樣:
mongodb://usr:password@localhost/myDB

讓我們繼續看下去~(倒)

我又來啦~~ ( ˊㄧˋ)/

在mongo裡面相關權限及重要設定都在admin這個db中,讓我們做以下修改:
 > use admin
switched to db admin
> db.addUser('root','1234');
{ "n" : 0, "connectionId" : 3, "err" : null, "ok" : 1 }
{
        "user" : "root",
        "readOnly" : false,
        "pwd" : "985ddff43226255e09d56b21ad602f69",
        "_id" : ObjectId("509e6d9b3877acdb8eee898c")
}

> db.auth('root','1qaz')
1
之後呢,再以--auth參數重新開啟MongoDB即可

2012年11月8日 星期四

[宅] 宅男臥軌日記(9) - Filters in controller

好像在前面的筆記裡有提到before_filter,但是沒有特別深入研究,拜讀了ihower大大的部落格並上網查了一下相關文章以後,在這裡做一個筆記整理。


filters

在Rails中,我們可以定義method在進入action之前、之中、之後進行,分別使用before_filter、after_filter和around_filter來實做。其中最常見的應該就是用before_filter來做權限驗證了:
before_filter :authenticate
上面的例子中接在before_filter後的是一個symbol,代表著要呼叫哪個method
before_filter最主要的功能還是在跨action的共用參數傳遞,在前面關於layout & style的文章中就有呼叫method,然後method回傳一個instance varible的例子。

在ihower大大的部落格中有提到,除了method以外,還能傳入code block以及物件。若傳入的是物件,Rails就會執行物件中的filter方法。

那code block呢?


在filter中傳入參數

前面有提到要在filter傳入method,要用symbol來指定method的名稱,但是我們沒辦法在symbol中加入參數("before_filter authenticate(arg)"明顯是個錯誤的寫法Orz),所以要傳入參數就要用以下兩個方法了:

1. code block

before_filter do |c|
c.send(:authorize, args)
end
或
before_filter :only => :show do |controller|
  controller.instance_eval do
    authorize(args)
  end
end

以上兩個方法我也還沒驗證過,改天來試試看XD


2. inline procs

這種方法最直覺,不過我一樣還沒驗證過能不能用XD
before_filter {authorize(args)}





[觀察] "我可是優秀的大學生耶,怎麼可以漲我學費呢!?"




http://ppt.cc/gtNF
看了PTT上的這篇文章,我有很多話想說。
文中的大意是一個年輕人家境不好,老爸當別人的保人欠了600多萬,但是他也是一路半工半讀到了大二,重點是:"沒有學貸"

高等教育=社會福利?

首先,這是一個本來就應該被矯正的觀念,誰說年輕人一定要讀大學?如果說讀完大學是能及時投入戰力的,那我舉雙手贊成,多繳一點稅給你們讀都無妨。但是怎麼常常聽到大學生說"以後要幹嘛?不知道耶"或是"同學都讀研究所,那我就跟著讀啦"。
當了太久的既得利益者,到大家發現資源分配不均以後,試圖矯正這個情況,大家就開始哇哇叫了....

讀大學好辛苦喔~每天讀書都讀不完了哭哭~ ^.<

摸著良心說,哪個學生沒有翹課過?更別提打混了。
如果你是真的很有心,認真的吸收每一分教育資源,即使在家境不好的狀況下也能自己打工堅持下去,那我覺得這樣的人到哪裡都能成功。
但是偏偏就有人是這樣:
(截圖自:http://goo.gl/jKHNL)

一個從高中開始貸款到大學畢業背了60萬的人,平均每年將近10萬。
那你等於是沒有試著還過嘛~每個月去超商打個工存個1萬元,扣掉生活費或多或少多少也能負擔一點了。
說到這裡,這個人究竟是真的認真讀書到沒有時間打工,還是覺得"反正學貸不用利息,不借白不借,晚點還沒差"?
我也剛脫離學生身分不久,知道當學生有多幸福,也知道大部分的學生過的是怎樣的日子。有些同學家境比較好,不用打工,零用錢可以爽爽花,但不代表家境不好的學生就得依樣畫葫蘆,跟風買什麼智慧型手機。要比手機名牌,為什麼不順便比一下人家的有錢老爸?有那個屁股才能拉那個屎,沒那個屁股請你乖乖去打工。

媒體已經很白癡了,拜託不要一起起舞

我這樣說不是要一竿子打翻一艘船,其實這樣的米蟲學生只是佔很少數。我雖然在學生階段也算是個米蟲,但好歹我也有在打工,也知道我享用了很多資源,不應該得了便宜還賣乖。但是越是米蟲的米蟲越會在媒體上大吐苦水,炒作群眾的情緒。
從前的大學生,是扮演著社會的先知先覺者,是推動革命、是推動社會運動的種子、是社會正義的捍衛者。當現在的大學生,享用著少少付出換回的高等教育資源時,還像個小孩子一樣的抱怨,我只覺得"又有一份教育資源被浪費了"


"什麼東西?
他們可是大~~~學生喔!"



2012年11月7日 星期三

[宅] javascript的模組化設計

最近看到幾篇相當棒的javascript模組化教學文章,在這邊收錄一下:
Javascript模块化编程(一):模块的写法
Javascript模块化编程(二):AMD规范
如何设计大规模 JavaScript 应用 (Part 1 - 概览)
Immediately-Invoked Function Expression (IIFE)

來為所學不精的自己做個學習筆記.....Q__Q


Immediately-Invoked Function Expression(IIFE)

IIFE其實就是像這樣的寫法:
var mod = (function(){var d=0; alert(d);})(); //typeof(mod)為"undifined"
也可以是
var mod = (function(){var d=0; alert(d);}()); //typeof(mod)為"undifined"
上面的寫法跟下面是不一樣的
var mod = (function(){var d=0; alert(d);}); //typeof(mod)為"function"

上面的寫法會直接執行function,但也就只是這樣而已,什麼都沒留下。若只是單純的IIFE其實只要這樣寫就行了:
(function(){var d=0; alert(d);})();



javascript的模組化

但既然要取得一個module我們當然要把內容給keep住,所以得要把需要的attribute包成object後return回來,所以改寫成這樣:
var mod = (function(){
    var d=0;
    var foo=function(){alert(d);};
    return {foo: foo}
})();
這樣我們就可以用mod.foo()來呼叫這個函數,也會alert 0,代表mod.foo()是找得到d的。
但是為什麼不直接向下面這樣定義object就好,還要這麼大費周章呢?
mod={foo: function(){alert(d);}, d:0}
主因就是用這樣的寫的話外部就能看到、也能改動mod.d,而模組化的mod中只找的到mod.foo,從外部是看不到d的。模組化後的物件可以含有像是java的private屬性~所以要讀寫這些屬性就得再寫getter和setter啦。



模組化的規範(CommonJS)

引述 Cat Chen大大的說法:一個模組系統至少要能解決兩個問題:dependencies的載入,以及private、public導出的分別。而CommonJS就是針對server side的javascript的相關規範,其中除了module的規範外還訂定了如Binary strings and buffers、Charset encodings、System process arguments、File system interface、Socket streams、Web server gateway interface、
Local and remote packages and package management等相關規範。更多SPEC可看官方文件:http://commonjs.org/impl/
其實Node.js就是遵照CommonJS的規範,從以下的官方範例就可以看出node.js的影子:

math.js
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
        sum += args[i++];
    }
    return sum;
};

increment.js
var add = require('math').add;
exports.increment = function(val) {
    return add(val, 1);
};

program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
module.id == "program";

很明顯的,在CommonJS訂定的module架構中,require到的是module裡所定義的export。



瀏覽器端的模組化規範 - AMD

但是在前面提到的CommonJS規範並不適用於瀏覽器環境,主因是在本機端是從磁碟機載入相關lib,但在client端可是得一個個下載,在同步的情況下必須等到載入完後才會進行接下來的程式,所以頁面看起來就會像是短暫的當機一樣。
這也是為什麼在client端必須以非同步的方式載入(就是同時載入相關module)。但是以非同步的方式載入又會出現一個問題,如果前面的module還沒載入完畢,就被後面的程式所呼叫了呢?
"Asynchronous Module Definition"(AMD)就是為了避免這些問題的出現所訂定的規範。
不同於CommonJS的require,AMD中的require()需要兩個參數:
require([module], callback);
而目前最常見的AMD實作就是require.js了,可以去官網研究一下。



2012年11月6日 星期二

[宅] 宅男臥軌日記(8) - 關於layout & style



依不同controller來assign Layout

要依不同controller來指定對應Layout(template),可以用layout選項來指定。就拿開發中所遇到的問題來舉例:
在還沒登入或登入錯誤時,我想指定一個特別的layout來呈現,因為會這些頁面都會經過devise的controller,基於這樣的前提我們可以在application controller下做以下的調整:
class ApplicationController < ActionController::Base
  protect_from_forgery
  
  layout :layout_by_resource

  protected

  def layout_by_resource
    if devise_controller?
      "guest"
    else
      "application"
    end
  end
end

"devise_controller?"是devise所提供的helper,用以判斷所在的controller是否為devise。
其實在一般情況下我們是不用直接修改application controller的,直接修改要呈現不一樣Layout的controller就可以。但是因為我們看不到devise controller,無法對他做修改,所以就寫在他的父類別讓他繼承這個特性。
而指定layout時其實還可以再做一些微調,例如:
layout "special", :only => :index
或
layout "special", :except => [:show, :edit, :new]

大家應該可以注意到以上的兩行和一開始的範例寫法有點不一樣,一個是使用symbol、一個是使用字串,這在意義上是不一樣的。使用symbol是call function,而使用字串就是直接去找這個名字的layout了。

Style

在一開始的application.css.erb中,我們可以在comments中找到以下兩行設定
*= require_self
*= require_tree .
雖然這兩行是寫在註解中,但他們還是有功用的(要把他disable掉只要刪掉"="就好了)。
require_self代表最後匯整的內容要包含"這個檔案"
require_tree代表最後匯整的內容要包含"所在資料夾下所有的檔案"

我們也可以很單純的require單一css,ex:
require bootstrap


同一個controller下為不同的view分配style sheet

不同controller對應各別layout在前面已經提過,但是有時候我們想用一樣的layout,但是是不同的style該怎麼辦呢?這時我們可以在template中動態的載入style sheet:

在View中:
<%=stylesheet_link_tag @foo %>

在Controller中:
before_filter :get_css_file
def get_css_file
  @foo = defined?(@style_type) ? 'normal' : 'special'
end

或是在你自己的邏輯定義@foo。