iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
自我挑戰組

30天從零到有,帶你進入程式的世界系列 第 29

[Day 29] Rails : 簡易部落格 2

  • 分享至 

  • xImage
  •  

當我們在Rails說CRUD的時候,代表我們通常是在做下面四件事情(新增,讀取,更改與刪除)
CRUD = create , read , update, delete

  • app/views/articles/new.html.erb 新增內容

    <h1>新增文章</h1>
    
    <%= form_with(model: @article, data:{ turbo: false }) do |f| %> 
      <div>
        <%= f.label :title, '標題' %>   
        <%= f.text_field :title %>
      </div>
      <div>
          <%= f.label :content, '內文' %>
          <%= f.text_area :content %>
          <%= f.submit %>
      </div>
    <% end %>
    
    

https://ithelp.ithome.com.tw/upload/images/20231010/20162648ojs487vDZK.png
點擊完save後,會有錯誤訊息"No route matches [POST] "/articles/new""
https://ithelp.ithome.com.tw/upload/images/20231010/20162648sXcW854OMd.png
這告訴我們目前routes中並沒有 post action 會對應到 "/articles/new" 這條路徑

  • config/routes.rb
    新增 : post "/articles", to: "articles#create"

    Rails.application.routes.draw do
      # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
    
      # get "/", to: "articles#index"
      root "articles#index" # 首頁的新寫法
      get "/articles", to: "articles#index"
      get "/articles/new", to: "articles#new"
      post "/articles", to: "articles#create"
    end
    

建立文章title跟content的資料庫

  1. rails g model Article title content:text
    建立一個model, 名稱是Article, 欄位1 : title⇒ 字串 , 欄位2 : content:text

  2. 執行完後會產生一個db檔

    • 會自動產生t.int :id
    • t.timestamps 執行時會展開成 t.datetime :created_at t.datetime :updeted_at
    class CreateArticles < ActiveRecord::Migration[7.0]
      def change
        create_table :articles do |t|
          t.string :title
          t.text :content
    
          t.timestamps
        end
      end
    end
    
  3. rails db:migrate

    • 如果看到下面的Migrations are pending. ⇒ 代表有migrate檔案還沒有作
    • 執行rails db:migrate
      https://ithelp.ithome.com.tw/upload/images/20231010/20162648L6S28AisKH.png
  • app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
    def index
    end

    def new
        @article = Article.new
    end

    def create
        @article = Article.new(article_params)
        if @article.save
	        redirect_to "/articles", notice: "文章新增成功"
		else
          # 沒有新增成功時拿new.html.erb 渲染
          render :new
        end
    end

    def article_params
      params.require(:article).permit(:title, :content)
    end
end

資料驗證

  • 確保title會是有填的
  • app/models/article.rb
class Article < ApplicationRecord
  validates :title, presence: true
end

顯示flash 訊息

  • app/views/layouts/application.html.erb 把通知訊息改成顯示到layout的檔案裡面
    <!DOCTYPE html>
    <html>
      <head>
        <title>WretchClone</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
    
        <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
        <%= javascript_importmap_tags %>
      </head>
    
      <body>
        **<%= flash[:notice] %>
        <%= flash[:alert] %>**
        <%= yield %>
      </body>
    </html>
    

解決不成功的時候跑版問題

  • 不成功的時候會把區塊加上 div :field_with_errors 造成跑版

  • ⇒ 改成display :inline
    https://ithelp.ithome.com.tw/upload/images/20231010/20162648t2bsYQ2JlT.png

  • app/assets/stylesheets/application.css

    .field_with_errors {
      display: inline;
    }
    
    .field_with_errors input {
      border: px solid red;
    }
    

https://ithelp.ithome.com.tw/upload/images/20231010/20162648ozxlnqhwRj.png


上一篇
[Day 28] Rails : 簡易部落格 1
下一篇
[Day 30] Rails : 簡易部落格 3
系列文
30天從零到有,帶你進入程式的世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言