2015年3月19日 星期四

新增一個Model Comment

配合post,增加comment功能,從上手指南7開始。
要注意一下中文的指南還是舊的,照著做會出錯的,大約從英文版的指南 6.4 Generating a Controller
開始看,再對照修改一下,以下列出重點。
先來產生 Model

rails generate model Comment commenter:string body:text post:references

沒有用到scaffolding,只建了model

/////////////////////////////////////////////////////////////////////////

CommentsController.rb的內容改成如下:
class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id]) #是這篇留言所屬的文章
    @comment = @post.comments.create(comment_params) #留言本身
    redirect_to post_path(@post) #最後回到show action顯示 app/views/posts/show.html.erb
  end
private
  def comment_params
    params.require(:comment).permit(:commenter, :body)
  end
end

////////////////////////////////////////////////////////////

app/views/posts/show.html.erb 增加了留言的顯示與輸入

<h2>Comments</h2>
<% @post.comments.each do |comment| %>
  <p>
    <b>Commenter:</b>
    <%= comment.commenter %>
  </p>
  <p>
    <b>Comment:</b>
    <%= comment.body %>
  </p>
<% end %>

<%= form_for([@post, @post.comments.build]) do |f| %>
  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

然後文章跟留言都可以運作,接著依指南往下做就好了。

2015年3月13日 星期五

理解 posts_controller.rb

抓幾行來理解一下:

before_action :set_post, only: [:show, :edit, :update, :destroy]

before_action 意思就是執行其它的action前要先執行指定的method,這裡就是set_post,
後面的only是限定要作用的action。

//////////////////////////////////////////////////////////////////

def index
    @posts = Post.all
end

進了Blog就是執行這個action,這裡把@posts設定好後,就會拿app/views/posts/index.html.erb
來顯示了。

//////////////////////////////////////////////////////////////////

def post_params
    params.require(:post).permit(:name, :title, :content)
end

params是http request所傳來一部份的值。
這可以取得post這個model的參數,後頭的permit是限定只取哪些參數

//////////////////////////////////////////////////////////////////

def create
    @post = Post.new(post_params) #取到的參數就可以實例化一個Post物件了。

//////////////////////////////////////////////////////////////////

respond_to do |format|
依請求的格式,返回不同的數據,如下:
format.html { redirect_to @post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: @post }

redirect_to和render是回應瀏覽器的方式
redirect_to @post 指示瀏覽器對一個 rul 再次發出請求,例如這邊是相當於讓瀏覽器執行 http://localhost:3000/posts/1 ,
render :show 就是把 show.html.erb 解析為html回傳給瀏覽器


2015年3月8日 星期日

Ruby入門

Rails上手指南要往下看的話,Ruby就算不熟至少也要入門一下,
這裡的二十分鐘體驗可以先參考
https://www.ruby-lang.org/zh_tw/documentation/quickstart/

這邊做個筆記

#{name} 字串內嵌,在字串中插入資料的方式
那個name是範例的變數,可以用其它的程式碼代換掉,例如1+1,
所以 "#{1+1}" 顯示出的字串為 2
只是這東西要放在""內,試了一下沒放在""裡就沒效果了。

類別的名稱要定義成常數,也就是第一個字為大寫 class Greeter
不然會吐錯誤訊息:class/module name must be CONSTANT

class內宣告的變數要加上 @ 符號,沒加會出現錯誤 undefined local variable or method

像這樣的變數 @name 類別外無法存取,所以有個 attr_accessor 的類別方法,如下使用:
class Greeter
  attr_accessor :name
end

為什麼連Greeter宣告都要再寫一遍?這展示了一個特性,你可以隨時修改類別。

respond_to 可以判斷物件是否有某種方法,下面有2種寫法
if @names.respond_to?("each")
if @names.respond_to? :each

可使用 each 方法的物件迭代的方法如下:
@names.each do |name|
  #這裡可以加入程式碼處理 name 變數
end

有一個特別的技巧 if __FILE__ == $0 可以拿來寫程式碼測試
__FILE__ 是檔案名 
$0       是執行檔名
所以不相同時表示是方法庫,就不會執行到裡面的程式了。

2015年3月5日 星期四

使用 scaffolding

Rails 的 鷹架 (scaffolding) 可用一行指令就為 Resource 建立 Model, Views 跟 Controller 程式碼。
下面要建立部落格文章管理功能。

建立 Post resource
rails generate scaffold Post name:string title:string content:text

執行 Migration 建立了 Posts 資料表
rake db:migrate

接著修改app/views/home/index.html.erb,再加一行
<%= link_to "My Blog", posts_path %>

刷新瀏覽器後點了連結就可以操作了。

順著指南從6.5開始看,在新增post時,若輸入空白也可以加入,所以要為欄位加上驗證

加入Validation (驗證)
打開app/models/post.rb在post類別內補上驗證的程式碼
class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
end

其實有沒有效果執行網頁就知道了,但有另一種方式就是console工具
執行rails console
接著就可以執行ruby的程式,也是一種方法。

往指南6.7往下看之前,先理解這些檔案之間的關連

以按下My Blog連結為例,就會執行到 app/controllers/posts_controller.rb 程式內 index 這個 action,
裡面的程式 @posts = Post.all 使用到了 app/models/post.rb 這個模組,
最後靠 app/views/index.html.erb 顯示出來

那麼為什麼會去執行index這action呢?還記得之前設定過的config/routes.rb檔嗎?
裡面有一行 resources :posts 有了這一行就會自動定義出以下七個action
get    '/posts'  => "posts#index",   :as => "posts"
post   '/posts' => "posts#create",  :as => "posts"
get    '/posts/:id' => "posts#show",    :as => "post"
put    '/posts/:id'      => "posts#update",  :as => "post"
delete '/posts/:id'      => "posts#destroy", :as => "post"
get    '/posts/new'      => "posts#new",     :as => "new_post"
get    '/posts/:id/edit' => "posts#edit",    :as => "edit_post"

所以按下My Blog連結,就是第一行的設定了。

到了這邊,沒碰過Ruby的話,要先補充一下,下面的連結可以好好參考。
https://ihower.tw/rails4/ruby.html

2015年3月1日 星期日

Hello, Rails

裝好Ruby On Rails後,可參考Rails指南的操作 http://guides.ruby.tw/rails3/getting_started.html
從第3點 建立新的 Rails 專案依序操作

先啟動rvm
source ~/.rvm/scripts/rvm

到目錄下
cd myblog

建資料庫
rake db:create

啟動web伺服器
rails server

///////////////////////////////////////////

準備好了就先作最簡單的練習 hallo rails

建立Controller與View
rails generate controller home index

編輯app/views/home/index.html.erb
加入<h1>Hello, Rails!</h1>

打開config/routes.rb,修改Rails首頁位置
找到 # root 'welcome#index' 這一行
改成 root 'home#index' 存檔

瀏覽器打開 http://localhost:3000 ,就會看到 Hello, Rails! 。

2015年2月28日 星期六

Ubuntu 12.04 安裝 Ruby on Rails

這篇已經說明的很清楚了,但我還是做個筆記。
http://blog.sudobits.com/2012/05/02/how-to-install-ruby-on-rails-in-ubuntu-12-04-lts/

1.先去github取得rails-installer.sh

2.執行 rails-installer.sh
sudo chmod +x rails-installer.sh
./rails-installer.sh

3.這時log顯示裝RVM出錯,於是先執行
curl -sSL https://rvm.io/mpapis.asc | gpg --import -

4.等key裝好了,再執行一次
./rails-installer.sh

5.安裝完成後log的提示
To start using RVM you need to run `source /home/chad/.rvm/scripts/rvm`
in all your open shell windows, in rare cases you need to reopen all shell windows.

6.接下來需要載入rvm
source ~/.rvm/scripts/rvm

7.然後就可以跑了,app_name可以改成自己定的名稱
rails new app_name
cd app_name
rails server

8.在本機開網頁試看看
http://localhost:3000

在命令列模式下按Ctrl-C可關閉server,那麼如何背景執行呢?
rails server -d
這個查help是可以知道,但是背景執行時如何關閉呢?如下:
kill -9 $(lsof -i :3000 -t)