Springok's Blog

Rails101學習筆記(2)-關於View與Helper

| Comments

在Rails中,View常常搭配helper使用,來作頁面的呈現,不管是內建的或是自訂helper都可以讓我們在設計頁面上更有一些彈性,例如:可能你會在不同的頁面但想要有相同的部分區塊呈現,或是類似的頁面產生邏輯,此時就可以藉由呼叫helper幫你達成。

在Rails架構底下,在產生Controller的同時,Rails就會自動幫你生一個同名的檔案,而我們會遵循一些慣例,把自訂helper放到對應的位置,各自controller使用的template就放在該檔案下,而像是整個網站或application都會用到的,我們就放到app/helpers/application_helper.rb。

順帶一提,helper是全域的,命名也很自由,不需要對應controller的名稱。

API參考:
http://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag
ihower大大關於Helper的詳細說明:
https://ihower.tw/rails4/actionview-helpers.html

Content_tag與搭配自訂helper實作:

Content_tag這個Rails的helper可產生一HTML小區塊,基本的用法如下:

content_tag(:p, "Hello world!”)
      # => <p>Hello world!</p>

也可以在裡面再包content_tag

content_tag(:div, content_tag(:p, "Hello world!"), class: "strong”)
      # => <div class="strong"><p>Hello world!</p></div>

在Rails101中則是使用在notice_message這個自訂的helper中,幫助在頁面中產生相關提示,像是”成功建立文章“等等,是個不錯的應用情境,如下所示:

application_helper.rb
module ApplicationHelper

  def notice_message
    alert_types = {notice: :success, alert: :danger}

    close_button_options = {class: "close",  "data-dismiss" => "alert", "aria-hidden" => true}
    close_button = content_tag(:button, "x", close_button_options)
     #上面這行就用了content_tag,並且相關設定包成了close_button_options這個hash,一來方便調整,二來也增加易讀性。


    alerts = flash.map do |type, message|
      alert_content = close_button + message

      alert_type = alert_types[type.to_sym] || type
      alert_class = "alert alert-#{alert_type} alert-dimssable"

      content_tag(:div, alert_content, class: alert_class)
    end
     #產生alert的區塊中也用了content_tag,先產出相關設定,最後一行再產生HTML區塊。


     alerts.join("\n").html_safe
  end
end

另外關於上面這段Code,也簡單補充幾個在實作時比較轉不過來的地方。

flash.map
flash是Rails內建的Method,幫助我們做一些即時的訊息提示。
map這個method是把值丟進後續指定的程式碼執行,並return執行結果。
另外,map跟each有點差別:
each是在Array底下的method,而map在Ruby裡面是包含在enumerable的mixin底下,詳細說明則可參考map vs. each

alert_class的樣式則是使用了bootstrap提供的alert type包含success, info, warning, danger。

Simple Format

simple format可把文字轉成具簡單格式的HTML區塊呈現的helper,用法如下:

my_text = "Here is some basic text...\n...with a line break.” #範例文字設定
simple_format(my_text)
# => "<p>Here is some basic text...\n<br />...with a line break.</p>"
# \n指的是換行,而遇到換行simple_format就會自動加入<br>斷行,如下所示
simple_format(my_text, {}, wrapper_tag: "div”)
# => "<div>Here is some basic text...\n<br />...with a line break.</div>"
# 預設是用<p>包起來,也可以將客制設定改為<div>
more_text = "We want to put a paragraph...\n\n...right there."
simple_format(more_text)
# => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
# 連續兩個以上的換行,會將前述文字用<p>包起來

而在Rails101中則用在下列區塊,提供自動換行:

posts_helper.rb
module PostsHelper
  def render_post_content(post)
    simple_format(post.context)
  end
end

Form_for與Simple Form

在專案中的頁面中,常常需要使用表單,Rails中也提供各式各樣的Form helpers供表單呈現與使用。

像是表格的各欄位通常會對應到model中的各個欄位,例如在頁面中個人資料表單的各欄位,對應到Person這個model中的屬性(attributes),像是姓名、出生年月日等等,而其中Form_for這個helper就可以幫我們直接把表格中各欄位跟model的各屬性綁在一起。

Form_for基本用法在Rails guideihower實戰聖經都有相當完整的解說。

而在Rails101中,使用了Simple form這個gem,這個gem讓產生頁面表單更有彈性,做更進一步的客製化,還可以整合bootstrap做一些樣式上的變化,不過因為Rails101所使用的表單與欄位設計上還沒有很複雜,暫時還感受不到他的威力,但還是可以透過其他前輩的文章感知一二,而基本用法推薦觀看Railscasts#234

時間格式的轉換

在Rails中時間格式有許多不同的變化,可透過to_s來選用自己需要的格式,用法如下:

time = Time.now          # => Thu Jan 18 06:10:17 CST 2007
time.to_s(:short)        # => "18 Jan 06:10"
time.to_s(:long)         # => "January 18, 2007 06:10"

像是create_at或是update_at都可以使用這個method

也有其他用文字敘述的呈現方式distance_of_time_in_words或是time_ago_in_words,用法如下:

from_time = Time.now
distance_of_time_in_words(from_time, from_time + 50.minutes)
# => about 1 hour
distance_of_time_in_words_to_now(Time.now - 30.second)
# => "less than a minute”

Comments

comments powered by Disqus