分享

[Rails][notes] CRUD -C: Create官網閱讀紀錄[3]


記錄自己官網文件閱讀的注釋與筆記
主要也是訓練自己閱讀英文挑戰
https://guides.rubyonrails.org/getting_started.html
官網 文件 注釋 筆記 rails

6 CRUDit Where CRUDit Is Due

大部分的網頁應用程序都與CRUD(建立、讀取、更新、刪除)操作相關
甚至可以發現大部分的網頁應用程序都是在做CRUD。Rails承認這一點
,並且提供與多功能來幫助簡化程式碼實現CRUD
讓我們來添加更多的應用程式功能來探索 Rails所提供的功能

6.1 Showing a Single Article

現在我們可以透過VIEW來顯示所有資料庫中所有Articles
的列表,讓我們來增加一個新的 VIEW 來顯示每一筆
Article 的標題與內文。
新增一個新的路徑對應到一個新的controller action
開啟config/routes.rb 新增一個show 路徑
  

Rails.application.routes.draw do

  root "articles#index"

  get "/articles", to: "articles#index"

  

  get "/articles/:id", to: "articles#show"

end

這是一個get 路徑,並且包含一個格而外的內容 :id
代表指定一個路由參數,這個路由參數將會擷取來自請求的一部分並且將該數值放入params Hash中 可以透過controller action 存取
example: 當接收到一個請求為GET http://localhost:3000/articles/1 ,其中1會被擷取成為:id,接著就可以在ArticlesController 中的show action 使用params[:id] 進行存取
接著我們在app/controllers/articles_controller.rb添加 show
  

class ArticlesController < ApplicationController

  def index

    @articles = Article.all

  end


  def show

    @article = Article.find(params[:id])

  end

end


在show action 中 使用 Article.find 透過params 中的id 找到擁有這個id的文章內容並存入@article,而@article這個實體變數將會被view存取,並渲染在
app/views/articles/show.html.erb.
然後我們在建立app/views/articles/show.html.erb,加入
  

<h1><%= @article.title %></h1>


<p><%= @article.body %></p>

接著可以透過瀏覽器訪問 http://localhost:3000/articles/1 看到頁面
這樣就完成屬於一篇文章的專屬頁面,我們可以透過index為每一天文章加上屬於自己的連結
開啟 app/views/articles/index.html.erb
  

<h1>Articles</h1>

<ul>

  <% @articles.each do |article| %>

    <li>

      <a href="/articles/<%= article.id %>">

        <%= article.title %>

      </a>

    </li>

  <% end %>

</ul>


6.2 Resourceful Routing

至目前為止 我們介紹了CRUD中的R; 讀取 
接著我們會介紹C;建立 你可能猜到要透過 建立 路徑NEW 及他的controller 跟 VIEW ,這裡我們介紹一個將CRUD組合的路徑,它叫做resource
Rails 提供一個路徑方法叫做 resources,它提供了一些常規的路徑集合,如同我們的Article,在我們建立C、R、U之前,我們將 原本的get 換成resources 如下
  

Rails.application.routes.draw do

  root "articles#index"


  resources :articles

end

透過指令  bin/rails routes 我們可以看到
  

bin/rails routes

Prefix Verb   URI Pattern                  Controller#Action         

root              GET    /                            articles#index     

articles         GET    /articles(.:format)          articles#index  

new_article    GET    /articles/new(.:format)      articles#new      

article           GET    /articles/:id(.:format)      articles#show              

                    POST   /articles(.:format)          articles#create 

edit_article     GET    /articles/:id/edit(.:format) articles#edit              
                    PATCH  /articles/:id(.:format)      articles#update              
                    DELETE /articles/:id(.:format)      articles#destroy


resources 方法提供 URL and path 方法,其中"Prefix"的欄位為前綴值搭配提供的後綴_url 或_path,例如article_path  
可以導向"/articles/#{article.id}",
透過這個方法整理app/views/articles/index.html.erb
  

<h1>Articles</h1>


<ul>

  <% @articles.each do |article| %>

    <li>

      <a href="<%= article_path(article) %>">

        <%= article.title %>

      </a>

    </li>

  <% end %>

</ul>

然而我們可以透過link_to  改寫 導向連結
link_to 第一個參數為文字,第二個參數為目的地
  

<h1>Articles</h1>


<ul>

  <% @articles.each do |article| %>

    <li>

      <%= link_to article.title, article %>

    </li>

  <% end %>

</ul>

6.3 Creating a New Article

CRUD中的C 在網頁應用程式中 會先要求使用者填寫一個表格然後適用 submit 來傳送表格 ,若是沒有錯誤則建立資料,若是有錯誤則重新顯示
頁面 並顯示錯誤,而這些步驟由controller 的new 和 create action 處理
讓我們新增這兩個action 在 app/controllers/articles_controller.rb
  

class ArticlesController < ApplicationController

  def index

    @articles = Article.all

  end


  def show

    @article = Article.find(params[:id])

  end


  def new

    @article = Article.new

  end


  def create

    @article = Article.new(title: "...", body: "...")


    if @article.save

      redirect_to @article

    else

      render :new

    end

  end

end


new 產生了一個article 的實體但是並未儲存,可以使用這個實體建立一個表單
並渲染在app/views/articles/new.html.erb
create action 將會建立一個具有包含title和body賦值的實體
可以嘗試使用save儲存資料若是成功可以透過"http://localhost:3000/articles/#{@article.id}" 
否則回到建立的表單,此時使用的title 與body 給予的是偽數值
接著我們來透過建立 表單由表單獲得數值
打開app/views/articles/new.html.erb
  

<h1>New Article</h1>


<%= form_with model: @article do |form| %>

  <div>

    <%= form.label :title %><br>

    <%= form.text_field :title %>

  </div>


  <div>

    <%= form.label :body %><br>

    <%= form.text_area :body %>

  </div>


  <div>

    <%= form.submit %>

  </div>

<% end %>

上述透過form_with 方法來建立表格,在form_with區塊中我們使用
label and text_field的方法來作為表單的建立適當的表單元素
form_with 產生對應的表單如下
  

<form action="/articles" accept-charset="UTF-8" method="post">

  <input type="hidden" name="authenticity_token" value="...">


  <div>

    <label for="article_title">Title</label><br>

    <input type="text" name="article[title]" id="article_title">

  </div>


  <div>

    <label for="article_body">Body</label><br>

    <textarea name="article[body]" id="article_body"></textarea>

  </div>


  <div>

    <input type="submit" name="commit" value="Create Article" data-disable-with="Create Article">

  </div>

</form>


6.3.2 Using Strong Parameters

當使用submit 後表格資料將與路徑參數一起透過params Hash 傳送至控制器
而控制器的create action 中可以後過params[:article][:title]及params[:article][:body]取得數值,然而這樣的填寫是冗長且容易出錯的
,此外惡意的使用者也可以透過表格傳送額外的資料傳覆蓋資料庫的數據
而Rails 也會透過ForbiddenAttributesError提醒我們有關的問題,因此我可以透過Strong Parameters來過濾params。
讓我們打開app/controllers/articles_controller.rb
使用article_params 來過濾提供給create 使用
  

class ArticlesController < ApplicationController

  def index

    @articles = Article.all

  end


  def show

    @article = Article.find(params[:id])

  end


  def new

    @article = Article.new

  end


  def create

    @article = Article.new(article_params)


    if @article.save

      redirect_to @article

    else

      render :new

    end

  end


  private

    def article_params

      params.require(:article).permit(:title, :body)

    end

end

6.3.3 Validations and Displaying Error Messages

如我們所見創造一筆資料需要多個步驟來完成,而處理無效的資料又是另一個多步驟的程序,Rails 提供了一個功能為  validations 幫助握們處理無效的用戶輸入資料,validations是在model儲存資料前檢查的規則,若有一項確認是錯誤的將會中止儲存,並提供錯誤訊息在errors 的屬性中供提取。
我可以打開app/models/article.rb
  

class Article < ApplicationRecord

  validates :title, presence: true

  validates :body, presence: true, length: { minimum: 10 }

end

第一個validation宣告title必須存在而title 的型態是字串,代表title必須包含一個非空白的字元。
第一個validation宣告body必須存在並且額外宣告必須至少10個字元
添加驗證後 讓我們修正表格讓其在出現錯誤時顯示出錯誤訊息
app/views/articles/new.html.erb
  

<h1>New Article</h1>


<%= form_with model: @article do |form| %>

  <div>

    <%= form.label :title %><br>

    <%= form.text_field :title %>

    <% @article.errors.full_messages_for(:title).each do |message| %>

      <div><%= message %></div>

    <% end %>

  </div>


  <div>

    <%= form.label :body %><br>

    <%= form.text_area :body %><br>

    <% @article.errors.full_messages_for(:body).each do |message| %>

      <div><%= message %></div>

    <% end %>

  </div>


  <div>

    <%= form.submit %>

  </div>

<% end %>

full_messages_for 這個方法將會返回一個陣列包含artiicle的錯誤訊息
  

  def new

    @article = Article.new

  end


  def create

    @article = Article.new(article_params)


    if @article.save

      redirect_to @article

    else

      render :new

    end

  end

在controller中可以看到當我們透過瀏覽器訪問http://localhost:3000/articles/new,
GET /articles/new 要求會被導向 new action ,new action 並
未執行儲存@article的動作,所以不會執行驗證也不會有錯誤訊息。
當使用者按下表格的submit ,提出POST /articles 要求 將會被導向
create action ,而create 確實執行儲存@article 並且執行validations確認
如果有產生validation錯誤訊息,@article會被中止儲存,
app/views/articles/new.html.erb 將會渲染出錯誤訊息

6.3.4 Finishing Up

現在我們可以透過訪問http://localhost:3000/articles/new.建立新的
article, 我們可以透過新建立的連結來訪問這個頁面
開啟 app/views/articles/index.html.erb
  

<h1>Articles</h1>


<ul>

  <% @articles.each do |article| %>

    <li>

      <%= link_to article.title, article %>

    </li>

  <% end %>

</ul>


<%= link_to "New Article", new_article_path %>

到此為止完成了 CRUD中的 C ; Create ,下一篇將繼續閱讀 如何 U; Update
#官網  #文件  #注釋  #筆記  #rails 
分類:學習

評論
上一篇
  • 下一篇
  • [Rails][notes] CRUD -U: Update官網閱讀紀錄[4]
  • 更多文章
    載入中... 沒有更多了