Rails5: Semantic UIを使用する
Semantic UIとはBootstrapのようなWebフレームワーク.
参考サイト:
Semantic UIをRails5.1に導入するためにやったこと - Qiita
Gemfileファイル
[Gemfile]
gem 'semantic-ui-sass', git: 'https://github.com/doabit/semantic-ui-sass.git' gem 'jquery-rails'
Semantic UIはjQueryを使用するのでjQueryも一緒にGemfileに記載してbundle intallを実行
$ bundle install
scssファイル
[app/assets/stylesheets/application.css]のファイル名を.cssから.scssに変更し、以下を追加.
$import-google-fonts: false; @import 'semantic-ui';
javascriptファイル
[app/assets/javascripts/application.js]に以下を追加する.
//= require jquery //= require jquery_ujs //= require rails-ujs //= require turbolinks // Loads all Semantic javascripts //= require semantic-ui //= require_tree .
以上
公式サイト
公式ドキュメントは以下.
semantic-ui.com
Ruby on RailでBootstrap を使用する
参考サイト
Ruby on Rails チュートリアル:実例を使って Rails を学ぼう初めてのRuby on rails Bootstrap導入編 [Memo for neko] - Qiita
GemfileへのBootstrap追加
[app/gemfile]
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.1.6' # bootstrap gem 'bootstrap', '~> 4.1.1'
gem 'bootstrap'を追加して bundle install .
$ bundle install
application.cssの編集
ファイル拡張子をscssに変更し、ファイルの最後に@importを追加
[/app/assets/stylesheets/application.css] -> [/app/assets/stylesheets/application.scss]
@import "bootstrap";
application.jsの編集
[app/assets/javascripts/application.js]
//= require bootstrap
以上!
使ってみる
適当にscaffoldして、migrate実行.
$ rails generate scaffold City name:string population:integer
$ rails db:migrate
Before
キャプチャ
コード
<p id="notice"><%= notice %></p> <h1>Cities</h1> <table> <thead>
After
キャプチャ
コード
<p id="notice"><%= notice %></p> <h1>Cities</h1> <table class="table"> <thead class="thead-dark">
Bootstrapのcssが反映されている.
Rails: "has_many", "blongs_to"でリレーショナルなテーブル関係を設定する_コントローラ、ビュー実装
前回、以下にて"has_many", "blongs_to"でリレーショナルなテーブル関係を設定したので実際に使えるようにコントローラとビューへ実装する.
teki-com.hateblo.jp
参考サイト
has_manyとbelongs_toについて。モデルの関連付けされたformの作り方 - Qiita
第11章ユーザーのマイクロポスト - Railsチュートリアル
html - No route matches missing required keys: [:id] - Stack Overflow
Rails のルーティング - Rails ガイド
RailsのScaffoldでネストしたResourceを作る - sometimes I laugh
ネストした form_with のリダイレクト先がエラーになってしまう - Qiita
ルーティングをネスト構造へ変更
以下でAuthorの下にBookを入れる.
[config/routes.rb]
resources :authors do resources :books end
ルーティングをネスト構造にすることで、以下のようにpathが自動的に割り当てられる.
Authorの設定
基本的に何もする必要なし。だけどBookの一覧表示へのリンクのみ作成しておく.
[app/views/authors/show.html.erb]
<%= link_to 'Book一覧', author_books_path(@author) %>
Book側の設定
ルーティング(path)が変わっているのでそれに合わせて変更する必要あり.
indexアクション
[app/controller/books_controller.rb]
FROM
# GET /books def index @books = Book.all end
TO
# GET /authors/:author_id/books def index @author = Author.find(params[:author_id]) @books = Author.find(params[:author_id]).books end
ビューを以下のようにパスを変更する.
[app/views/authors/index.html.erb]
<td><%= link_to 'Show', author_book_path(@author,book) %></td> <td><%= link_to 'Edit', edit_author_book_path(@author,book) %></td> <td><%= link_to 'Destroy', author_book_path(@author,book), method: :delete, data: { confirm: 'Are you sure?' } %></td>
showアクション
コントローラ
# GET /authors/:author_id/books/1 def show @author = Author.find(params[:author_id]) @books = Author.find(params[:author_id]).books end
ビュー
<%= link_to 'Edit', edit_author_book_path(@author,@book) %> <%= link_to 'Back', author_books_path(@author) %>
共通処理の"_form.html.erb"の一行目の処理にauthorを追加する.
[app/view/books/_form.html.erb]
<%= form_with(model: [author,book], local: true) do |form| %>
newおよびcreateアクション
コントローラ
[app/controllers/books_controller.rb]
# GET /authors/:author_id/books/new def new @author = Author.find(params[:author_id]) @book = Author.find(params[:author_id]).books.new end # POST /authors/:author_id/books def create @author = Author.find(params[:author_id]) @book = Author.find(params[:author_id]).books.new(book_params) respond_to do |format| if @book.save format.html { redirect_to [@author,@book], notice: 'Book was successfully created.' } ... else ... end end end
ビュー
[app/views/books/new.html.erb]
<%= render 'form', author: @author, book: @book %> <%= link_to 'Back', author_books_path(@author) %>
もう一度"_form.html.erb"に移動し、今度は16行目をの"form.text_field :author_id"とすることで初期値にauthor_idとしておく
<%= form.text_field :author_id, id: :book_author %>
editおよびupdateアクション
コントローラ
# GET /authors/:author_id/books/1/edit def edit @author = Author.find(params[:author_id]) @books = Author.find(params[:author_id]).books end # PATCH/PUT authors/:author_id/books/1 def update @author = Author.find(params[:author_id]) if @book.update(book_params) format.html { redirect_to [@author,@book], notice: 'Book was successfully updated.' } ... else ... end end end
ビュー
<%= render 'form', author: @author, book: @book %> <%= link_to 'Edit', edit_author_book_path(@author,@book) %> <%= link_to 'Back', author_books_path(@author) %>
updateはビューを持っていないので省略
Destroyアクション
コントローラ
[app/controllers/books_controller.rb]
# DELETE authors/:author_id/books/1 def destroy ... format.html { redirect_to author_books_url, notice: 'Book was successfully destroyed.' } ... end end private # Use callbacks to share common setup or constraints between actions. def set_book @book = Author.find(params[:author_id]).books.find(params[:id]) end ... end
Destroyはビューを持っていないので省略
以上.すごく荒削りにしか開催していないのであまり参考にしないでください.
いずれわかりやすく書き直します.今はメモ程度.
Rails: "has_many", "blongs_to"でリレーショナルなテーブル関係を設定する
UserとPostのような1つに対して多くのアイテムを持つような時の設定方法.
参考サイト
Rails4で1対多のリレーションをモデルに実装する - Rails Webook
Active Record の関連付け (アソシエーション) - Rails ガイド
railsのbelongs_toとhas_manyとreferencesの使い方について整理する - 巨人の足元でたじlog
scaffoldで下準備
$ rails generate scaffold Author name:string
$ rails generate scaffold Book author:references published_at:datetime
"author:references"に関して、"author_id:integer"でもよいが、referencesとすることで勝手にRailsがidを作ってくれるみたい.
Author側の設定
Author側に:booksをたくさん持っていいよ(has_many)と設定する.
[app/models/user.rb]
class User < ApplicationRecord has_many :books, dependent: :destroy end
Note: 1対多のリレーション時はhas_manyは複数形にする.
"dependent: :destroy"でUserが消されたときに一緒に削除されるよう設定.
他にもオプションがあるので参考サイト参照.
Book側の設定
Book側にauthorについていく(belongs_to)を設定する.
[app/models/post.rb]
class Post < ApplicationRecord belongs_to :author end
デフォルトでは使用するキーはauthor_idが使われる.
キーを変更したい(外部キーを使いたい)場合はforeign_keyオプションで変更できる.
Note: 1対多のリレーション時はbelongs_toは単数形にする.
関連付けのメリット(意味)
"has_many","belongs_to"による関連付けにより以下のメソッドが使えるようになる.
Rails Consoleで試す.
$ rails console
いつも通りに新規作成およびテーブル登録
author1=Author.create(name:'Natsume')
book1を追加してauthor1とリンクさせて作成、テーブルへ追加
book1=author1.books.create(published_at:Time.parse("1905010100000000"))
以下実行結果."author_id"を設定していないのに自動的に設定されていることがわかる.
#<Book id: 3, author_id: 2, published_at: "1905-01-01 00:00:00", created_at: "2019-05-19 12:38:56", updated_at: "2019-05-19 12:38:56">
Ruby on Rails "Active Admin" + "CarrierWave"で画像アップロード
参考サイト
【Rails】PaperClip + active_adminで画像をアップロード - avosalmonのブログ
ruby on rails - Use Carrierwave with Active Admin - Stack Overflow
今回は以下で作成したActive Admin済みのBookモデルを使用します.
"$ rails generate migration AddImageToBook image:string"でカラムを追加して、"CarrierWave"のインストールと設定が状態とします.
詳細は以下の記事を参照
teki-com.hateblo.jp
追加
ActiveAdmin.register Book do permit_params :title, :company, :image form do |f| f.inputs "Books" do f.input :title f.input :company f.input :image, :as => :file end f.actions end show do |item_image| attributes_table do row :title row :company # show画面で画像を表示するためのタグを追加 row :image do image_tag(book.image.url) end end end end
追加フォーム
確認フォーム
削除
特に気にすることなく管理画面の"delete"をすると画像も削除される.
Ruby on Rails gem "Active Admin"で管理画面実装
参考サイト
Rails5 + ActiveAdmin 使い方 - Qiita
ActiveAdmin でのモデルの追加方法 (基本) - Qiita
Active Adminのインストール
GemfileにActive Admin本体およびそれに必要なdeviseを追加しインストールする.
[Gemfile]
# Active Admin gem 'activeadmin', github: 'activeadmin' gem 'inherited_resources', github: 'activeadmin/inherited_resources' # 認証用 gem 'devise'
$ bundle install
インストーラの実行
$ rails generate active_admin:install
管理者情報の変更(必要であれば)
インストーラの実行により"db/seeds.rb"に初期ユーザの情報が記載されているので必要に応じて編集する.
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
マイグレーション
migrationの実行
$ rails db:migrate $ rails db:seed
これでActive Adminの導入は完了.編集対象のモデルを追加する場合は以下を実行.
モデル(管理画面で表示する)の追加
モデル名はBookです.
$ rails generate scaffold Book title:string company:string
マイグレーションし、
$ rails db:migrate
リソースを作成.”app/admin/books.rb”が作成される.
$ rails generate active_admin:resource Book
"ルートアドレス/admin"にアクセスし、ログインすると”Books”が追加されている.
最後に”app/admin/books.rb”にpermit_paramsを設定することで新規作成ができるようになる.
ActiveAdmin.register Book do permit_params :title, :company end
*
Ruby on Rails gem "CarrierWave":画像削除実装
scaffoldで下準備
scaffoldを用いて生成.モデル名はPostとした.
$ rails g scaffold Post name:string image:string
Viewの変更(index)
createアクションで画像が設定されていないとnilが返ってくるため、nilでなければ画像を表示するように設定.
<table> <thead> <tr> <th>Name</th> <th>Image</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @posts.each do |post| %> <tr> <td><%= post.name %></td> <td><% unless post.image.url.nil? %> <%= image_tag post.image.url %> <% end %></td> <td><%= link_to 'Show', post %></td> <td><%= link_to 'Edit', edit_post_path(post) %></td> <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table>
Viewの変更(create)
画像登録フォームを作成するため[/app/views/posts/_form.html.erb]を以下のように変更.
<div class="field"> <%= form.label :image %> <p><%=form.label "画像をアップロード" %><br><%= form.file_field :image %></p> </div>
不格好だけどこんな感じ.
Destroy アクションに画像削除用コマンドを記入
以下サイトより、"remove_{カラム名}!"で削除できるとのことなのでdestroyアクションの初め2行に追加.
CarrierWaveでアップロードしているファイルを削除する - Qiita
def destroy @post.remove_image! @post.save @post.destroy respond_to do |format| format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' } format.json { head :no_content } end end
削除完了.