개발자가 내팔자

[Ruby on Rails] 공식문서와 함께 하는 30분 만에 블로그 만들기! - 게시판 꾸미기/유효성검증 본문

WEB/Back-end

[Ruby on Rails] 공식문서와 함께 하는 30분 만에 블로그 만들기! - 게시판 꾸미기/유효성검증

야생의 개발자 2022. 8. 8. 19:10

Ruby on Rails

https://rubyonrails.org/

 

Ruby on Rails

A web-app framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

rubyonrails.org

 

 

저번 포스트에서 만든 블로그가 잘 돌아가는 것을 확인했는가?
뭔가 부족함을 느꼈다면 이제부터 하나씩 추가해주기로 하자.

블꾸 (블로그 꾸미기) - 스타일 넣어주기

기능은 잘 돌아가지만 너무 못생겼으니까 아래 한 줄을태그 사이에 넣어주도록 하자.

<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">

블로그가 좀 더 예뻐지는 것을 확인할 수 있다.

JSON도 되나요?

http://127.0.0.1/posts.json 이라고 치면 json으로 결과를 볼 수 있다.

app/controllers/posts_controller.rb 에 이런 식으로 json을 내려주고 있기 때문이다.

    respond_to do |format|
      if @post.save
        format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end

Validation (유효성 검증) 추가하기

이제 유효성 검증 과정을 추가해보자.
지금은 제목에 딱히 아무 내용도 적지 않아도 글이 등록될 것이다.
이건 좀 이상하다고 생각하지 않는가?

이제 드디어 app/models/post.rb를 건드려보자.

class Post < ApplicationRecord
  validates_presence_of :title
end

validate_presence_of 라는 것을 추가하면 title이 없을 경우 에러 메세지가 나타나며 글 생성을 막는다.

console 이용하기

아래 명령어를 통해 CLI로 데이터를 직접 조작할 수 있다.

rails console

첫 번째 Post 가져오기

Post.first

새로운 Post 생성

Post.create! title: "From the console", content: "Nice!"

조건에 맞는 데이터 살펴보기

Post.where(created_at: Time.now.all_day)

Post.where(created_at: Time.now.all_day).to_sql

Post.where(created_at: Time.now.yesterday.all_day)

Post.where(created_at: Time.now.yesterday.all_day).to_sql

게시글 꾸미기

글을 쓸 때 강조도 하고 싶고, 이미지도 넣고 싶은데 너무 심심하다면?

❯ rails action_text:install
      append  app/javascript/application.js
      append  config/importmap.rb
      create  app/assets/stylesheets/actiontext.css
To use the Trix editor, you must require 'app/assets/stylesheets/actiontext.css' in your base stylesheet.
      create  app/views/active_storage/blobs/_blob.html.erb
      create  app/views/layouts/action_text/contents/_content.html.erb
Ensure image_processing gem has been enabled so image uploads will work (remember to bundle!)
        gsub  Gemfile
       rails  railties:install:migrations FROM=active_storage,action_text
Copied migration 20220808094643_create_active_storage_tables.active_storage.rb from active_storage
Copied migration 20220808094644_create_action_text_tables.action_text.rb from action_text
      invoke  test_unit
      create    test/fixtures/action_text/rich_texts.yml

현재 예제에서는 로컬에 저장하고 있지만, 실제 product에서는 s3같은 클라우드 저장소에 연결하는 것이 좋다.

아래 명령어를 입력하고

❯ bundle
Using rake 13.0.6
Using concurrent-ruby 1.1.10
Using i18n 1.12.0
Using minitest 5.16.2
Using tzinfo 2.0.5
Using activesupport 7.0.3.1
Using builder 3.2.4
Using erubi 1.11.0
Using racc 1.6.0
Using nokogiri 1.13.8 (arm64-darwin)
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.18.0
Using rails-html-sanitizer 1.4.3
Using actionview 7.0.3.1
Using rack 2.2.4
Using rack-test 2.0.2
Using actionpack 7.0.3.1
Using nio4r 2.5.8
Using websocket-extensions 0.1.5
Using websocket-driver 0.7.5
Using actioncable 7.0.3.1
Using globalid 1.0.0
Using activejob 7.0.3.1
Using activemodel 7.0.3.1
Using activerecord 7.0.3.1
Using marcel 1.0.2
Using mini_mime 1.1.2
Using activestorage 7.0.3.1
Using mail 2.7.1
Using digest 3.1.0
Using timeout 0.3.0
Using net-protocol 0.1.3
Using strscan 3.0.4
Using net-imap 0.2.3
Using net-pop 0.1.1
Using net-smtp 0.3.1
Using actionmailbox 7.0.3.1
Using actionmailer 7.0.3.1
Using actiontext 7.0.3.1
Using public_suffix 4.0.7
Using addressable 2.8.0
Using bindex 0.8.1
Using msgpack 1.5.4
Using bootsnap 1.13.0
Using bundler 2.3.7
Using matrix 0.4.2
Using regexp_parser 2.5.0
Using xpath 3.2.0
Using capybara 3.37.1
Using childprocess 4.1.0
Using io-console 0.5.11
Using reline 0.3.1
Using irb 1.4.1
Using debug 1.6.1
Using ffi 1.15.5
Using mini_magick 4.11.0
Using ruby-vips 2.1.4
Using image_processing 1.12.2
Using method_source 1.0.0
Using thor 1.2.1
Using zeitwerk 2.6.0
Using railties 7.0.3.1
Using importmap-rails 1.1.5
Using jbuilder 2.11.5
Using puma 5.6.4
Using rails 7.0.3.1
Using rexml 3.2.5
Using rubyzip 2.3.2
Using websocket 1.2.9
Using selenium-webdriver 4.3.0
Using sprockets 4.1.1
Using sprockets-rails 3.4.2
Using sqlite3 1.4.4
Using stimulus-rails 1.1.0
Using turbo-rails 1.1.1
Using web-console 4.2.0
Using webdrivers 5.0.0
Bundle complete! 16 Gemfile dependencies, 78 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

db에 migrate을 해준다

❯ rails db:migrate
== 20220808094643 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs, {:id=>:primary_key})
   -> 0.0012s
-- create_table(:active_storage_attachments, {:id=>:primary_key})
   -> 0.0009s
-- create_table(:active_storage_variant_records, {:id=>:primary_key})
   -> 0.0005s
== 20220808094643 CreateActiveStorageTables: migrated (0.0027s) ===============

== 20220808094644 CreateActionTextTables: migrating ===========================
-- create_table(:action_text_rich_texts, {:id=>:primary_key})
   -> 0.0013s
== 20220808094644 CreateActionTextTables: migrated (0.0013s) ==================

app/models/post.rb

has_rich_text 한 줄 추가해준다.

class Post < ApplicationRecord
  validates_presence_of :title
  has_rich_text :content
end

app/views/posts/_form.html.erb

아래 코드를 찾아서

<%= form.text_area :content %>

아래와 같이 rich_를 추가해준다.

<%= form.rich_text_area :content %>

작성 일시를 좀 더 힙하게!

아래 명령어로 local-time을 내려받는다.

./bin/importmap pin local-time

config/importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "local-time", to: "https://ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js"

local-time이 추가된 것을 확인할 수 있다.

app/javascript/application.js 에서

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"

import LocalTime from "local-time"
LocalTime.start()

위와 같이 아래 두 줄을 추가해준다.

app/views/posts/_post.html.erb에서 제목과 내용 사이에 아래와 같이 추가해준다.

  <p>
    Posted <%= time_tag post.created_at, "data-local": "time-ago" %>
  </p>

근데 이 방식은 로컬에 설치를 해서 쓰는 게 아니라 api를 이용하는 방식이기 때문에 네트워크 연결이 안되면 잘 동작하지 않을 수 있다.
그래서 불안하다면 직접 다운로드를 받을 수도 있다. pin이 바뀐 것을 확인할 수 있지만, 이렇게 해도 똑같이 동작한다.

./bin/importmap pin local-time --download

끝?

축하한다.
여기까지 왔다면 이제 웬만한 블로그 기능은 잘 되는 것 같다.
다음 포스트에서는 댓글 기능을 추가해보도록 하자!

 

+

https://github.com/libvips/ruby-vips/issues/284

 

Little help? Could not open library 'glib-2.0.0': dlopen(glib-2.0.0, 5): image not found. · Issue #284 · libvips/ruby-vips

Hi team (John? Anyone?) Hoping for some help. I've spent hours on github/stackoverflow trying to triage this issue. Admittedly, I'm new to ruby and very new to getting development environme...

github.com

m1 맥북에서는 post를 볼 때 에러가 나서 파일이 안보일 수 있다.

 

에러 메세지는 아래와 같은데 위 이슈에서 해결한 사람들이 있는 것 같으니 참고.

LoadError (Could not open library 'glib-2.0.0': dlopen(glib-2.0.0, 0x0005): tried: 'glib-2.0.0' (no such file), '/usr/local/lib/glib-2.0.0' (no such file), '/usr/lib/glib-2.0.0' (no such file), '/Users/luna/Projects/rubyProject/demo2/glib-2.0.0' (no such file), '/usr/local/lib/glib-2.0.0' (no such file), '/usr/lib/glib-2.0.0' (no such file).
Could not open library 'libglib-2.0.0.dylib': dlopen(libglib-2.0.0.dylib, 0x0005): tried: 'libglib-2.0.0.dylib' (no such file), '/usr/local/lib/libglib-2.0.0.dylib' (no such file), '/usr/lib/libglib-2.0.0.dylib' (no such file), '/Users/luna/Projects/rubyProject/demo2/libglib-2.0.0.dylib' (no such file), '/usr/local/lib/libglib-2.0.0.dylib' (no such file), '/usr/lib/libglib-2.0.0.dylib' (no such file)):
Comments