- 投稿日:2021-02-13T23:51:39+09:00
管理者権限付与後、本番環境にrails db:seedをするまで(Active Storageも含む)
はじめに
管理者権限の付与方法については以下記事に記載しております。
https://qiita.com/narimiya/items/8d21b18db9c75b1dde2d
前提
●管理者権限機能は実装済み
●usersテーブルの情報
XXX_devise_create_users.rb〜省略〜 t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" t.string :nickname, null: false t.text :occupation, null: false t.text :position, null: false t.date :birth_day, null: false t.integer :sex_id, null: false t.boolean :admin, default: false 〜省略〜バージョン
rubyのバージョン ruby-2.6.5
Railsのバージョン Rails:6.0.0gemについて
・gem 'devise'
・gem 'rails_admin', '~> 2.0.0.beta'
・gem 'cancancan'記事の内容
管理者についての情報をseeds.rbに記述し、本番環境にてseeds.rbの内容を
反映するまでの手順を述べています。実装の全体像
●ローカル環境
①seeds.rbの記述
②rails db:seedの実行●gitにてマージ
●本番環境
④デプロイ
⑤heroku run rails db:seedの実行実装の手順
①seeds.rbの記述
Active Storageでimageカラムを取り込んでいるので、usersテーブルにimageカラムをattachする。
※seeds.rb内の一番下の記述
(なお画像についてはimageカラムと定義している。)db.seeds.rbuser = User.create!(email: "admin@example.jp", password: "abcd1234", password_confirmation: "abcd1234", nickname: "管理者", occupation: "管理者", position: "管理者", birth_day: "2000-10-10", sex_id: "2", admin: true) user.image.attach(io: File.open(Rails.root.join("app/assets/images/homekatajiten.png")), filename: "homekatajiten.png")②rails db:seedの実行
rails db:seedを実行して初期データを投入する。
$ rails db:seed③デプロイ
$ git push heroku master④heroku run rails db:seedの実行
本番環境にもlocal同様の初期データを投入する。
$ heroku run rails db:seed確認
最後は反映されているか確認を行う。
$ heroku open実行できていれば管理者アカウントでログイン後、(本番環境URL)/adminで以下のような画面になっていれば成功です。
以上です。
- 投稿日:2021-02-13T21:38:28+09:00
【Railsチュートリアル】第7章 ユーザー登録①
第7章 ユーザー登録
はじめに
本章の目的
- ユーザー登録機能の追加
- HTML フォームを使ってWebアプリケーションに登録情報を送信
- ユーザーを新規作成して情報をデータベースに保存
- ユーザーを表示するためのページを作成
- 統合テストに対して、 いくつかのテストを追加
7.1 ユーザーを表示する
本節では、ユーザーの名前とプロフィール写真を表示するためのページを作成していく。
ユーザープロフィールページの最終的な目標は、ユーザーのプロフィール写真と基本ユーザーデータ、そしてマイクロポストの一覧を表示すること。7.1.1 デバッグとRails環境
レイアウトにデバッグ情報を追加する。
app/views/layouts/application.html.erb#もしRails.env.development(development=開発環境)だったらデバッグ情報を表示せよ <%= debug(params) if Rails.env.development? %>演習 1
ブラウザから /about にアクセスし、デバッグ情報が表示されていることを確認してください。このページを表示するとき、どのコントローラとアクションが使われていたでしょうか?paramsの内容から確認してみましょう。
debug_info--- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess controller: static_pages action: about permitted: falseコントローラ: static_pages, アクション: about
演習 2
Railsコンソールを開き、データベースから最初のユーザー情報を取得し、変数userに格納してください。その後、puts user.attributes.to_yamlを実行すると何が表示されますか? ここで表示された結果と、yメソッドを使ったy user.attributesの実行結果を比較してみましょう。
console>> user = User.first (3.6ms) SELECT sqlite_version(*) User Load (3.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Michael Hartl", email: "michael@example.com", created_at: "2021-02-09 06:34:49", updated_at: "2021-02-09 06:34:49", password_digest: [FILTERED]> >> puts user.attributes.to_yaml --- id: 1 name: Michael Hartl email: michael@example.com created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2021-02-09 06:34:49.836041000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone name: Etc/UTC time: *1 updated_at: !ruby/object:ActiveSupport::TimeWithZone utc: &3 2021-02-09 06:34:49.836041000 Z zone: *2 time: *3 password_digest: "$2a$12$c6TWZz21VWw7m8bDorgz9uR3XMXaWbMdtzmV.r6krzwzy59OmF7gO" => nil >> y user.attributes --- id: 1 name: Michael Hartl email: michael@example.com created_at: !ruby/object:ActiveSupport::TimeWithZone utc: &1 2021-02-09 06:34:49.836041000 Z zone: &2 !ruby/object:ActiveSupport::TimeZone name: Etc/UTC time: *1 updated_at: !ruby/object:ActiveSupport::TimeWithZone utc: &3 2021-02-09 06:34:49.836041000 Z zone: *2 time: *3 password_digest: "$2a$12$c6TWZz21VWw7m8bDorgz9uR3XMXaWbMdtzmV.r6krzwzy59OmF7gO" => nil同じ
7.1.2 Usersリソース
ユーザー情報をWebアプリケーション上に表示する。
RESTアーキテクチャ
* データの作成、表示、更新、削除をリソース(Resources)として扱う。
* HTTP標準には、これらに対応する4つの基本操作(POST、GET、PATCH、DELETE)を各アクションに割り当てていく。ユーザーをリソースとみなす
= id=1のユーザーを参照する
= "/users/1というURLに対してGETリクエストを発行する"config/routes.rbresources :users #この行を追加するユーザーのURLを生成するための多数の名前付きルート(5.3.3)と共に、RESTfulなUsersリソースで必要となるすべてのアクションが利用できるようになる
演習 1
埋め込みRubyを使って、マジックカラム(created_atとupdated_at)の値をshowページに表示してみましょう(リスト 7.4)。
app/views/users/show.html.erb<%= @user.name %>, <%= @user.email %>, <%= @user.created_at %>, <%= @user.updated_at %>演習 2
埋め込みRubyを使って、Time.nowの結果をshowページに表示してみましょう。ページを更新すると、その結果はどう変わっていますか? 確認してみてください。
Michael Hartl, michael@example.com, 2021-02-09 06:34:49 UTC, 2021-02-09 06:34:49 UTC, 2021-02-12 23:11:30 +0900
(更新後)
Michael Hartl, michael@example.com, 2021-02-09 06:34:49 UTC, 2021-02-09 06:34:49 UTC, 2021-02-12 23:11:53 +0900更新をかけると、表示時間も更新される。
7.1.3 debuggerメソッド
debuggerメソッドを使う。
演習 1
showアクションの中にdebuggerを差し込み(リスト 7.6)、ブラウザから /users/1 にアクセスしてみましょう。その後コンソールに移り、putsメソッドを使ってparamsハッシュの中身をYAML形式で表示してみましょう。ヒント: 7.1.1.1の演習を参考にしてください。その演習ではdebugメソッドで表示したデバッグ情報を、どのようにしてYAML形式で表示していたでしょうか?
console(byebug) p = params <ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"1"} permitted: false> (byebug) puts p.to_yaml --- !ruby/object:ActionController::Parameters parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess controller: users action: show id: '1' permitted: false nil演習 2
newアクションの中にdebuggerを差し込み、/users/new にアクセスしてみましょう。@userの内容はどのようになっているでしょうか? 確認してみてください。
console[1, 10] in /home/vagrant/work/sample_app2/app/controllers/users_controller.rb 1: class UsersController < ApplicationController 2: 3: def show 4: @user = User.find(params[:id]) 5: end 6: 7: def new 8: debugger => 9: end 10: end (byebug) @user nil7.1.4 Gravatar画像とサイドバー
* 各ユーザーのプロフィール写真のあたりをもう少し肉付けし、サイドバーも作り始める。
* Gravatar(Globally Recognized AVATAR)をプロフィールに導入する。app/views/users/show.html.erb<% provide(:title, @user.name) %> <h1> #gravatar_forヘルパーメソッドを使い@userのプロフィール画像を表示せよ <%= gravatar_for @user %> # @userのnameを表示 <%= @user.name %> </h1>console$ rails console >> user = User.first >> user.update(name: "Example User", ?> email: "example@railstutorial.org", ?> password: "foobar", ?> password_confirmation: "foobar") => trueemailでGravatar上とRailsチュートリアルのロゴを既に紐付けてある。
app/views/users/show.html.erb<% provide(:title, @user.name) %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <h1> <%= gravatar_for @user %> <%= @user.name %> </h1> </section> </aside> </div>演習 1
(任意)Gravatar上にアカウントを作成し、あなたのメールアドレスと適当な画像を紐付けてみてください。メールアドレスをMD5ハッシュ化して、紐付けた画像がちゃんと表示されるかどうか試してみましょう。
- Gravatar
- サイト下部の「Gravatarを作成」をクリック
- アカウント開設
- プロフィールの画像を変更
Rails console
でuser
にGravatar
のメールアドレスをupdaterails s -b 0.0.0.0
で確認。変更されていました。演習 2
7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。重要: この改善したヘルパーは10.3.1で実際に使います。忘れずに実装しておきましょう。
実装のみなので省略。
演習 3
オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数(Keyword Arguments)」でも実現することができます。先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この2つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。
動作確認のみなので省略。
コードが完結になるだけだろうか?
- 投稿日:2021-02-13T21:23:20+09:00
Rails:モデルの命名規則を破ったらエラーが出ました【NameError】【uninitialized constant】
Rails:モデルの命名規則を破ったらエラーが出ました【NameError】【uninitialized constant】
エラー画面
エラー説明
uninitialized constant:「定義したクラスを読むことができないよ」
(Railsでは定数やclassが定義されていないという意味のエラー)
NameError:「そんな名前は定義されてないよ」
(定義されていないローカル変数やメソッドが呼び出されている場合に、発生するRubyのエラー)原因
classの命名規則が正しくできていなかった
誤:「Deliver_fee」
正:「DeliverFee」RailsのDBモデルの命名規則
単語が1つの場合
例)モデルの名前が「Deliver」
モデル名:deliver
モデルクラス名:Deliver
ファイル名:deliver.rb
テーブル名:delivers単語が複数の場合
例)モデル名が「Deliver Fee」
モデル名:deliver fee
モデルクラス名:DeliverFee
ファイル名:deliver_fee.rb
テーブル名:deliver_fees
Railsは命名規則がきっちりしているので、ファイル名を命名規則に従わせないとファイルが見つからないとエラーが出てしまうようです。
気をつけましょう。以上です。
- 投稿日:2021-02-13T20:34:37+09:00
Jupyter Notebook で Ruby が使えるってま!?
概要
会社でRailsを使って開発をしている関係でRubyのコードを試したいことが多々ありました。
Paizaとかブラウザで実行できるものもあるがPythonみたくJupyter notebookでできないかなと思っていました。そこで調べるとRubyをJupyter notebookに入れることが出来ることが判明(゚∀゚) 実際に導入する手順がわかったので今後PCが壊れたときのためにインストール方法をメモします。
条件
言語 ver Ruby 2.10 以上 Jupyter Notebook -- ※Ruby と jupyter notebookの道入がまだの人は以下の記事よりそれぞれのインストールを済ませて下さい。
・Rubyのインストール
【完全版】MacでRails環境構築する手順の全て・Jupyter Noteboookのインストール
① anacondaのインストール
Anaconda(Python3)インストール手順<macOS用>② anacondaのPATHの通し方
AnacondaのPATHの設定③ Jupyter notebook のインストール
Installing the Jupyter Software方法
iRubyのgithubをもとにインストールを進めていきます。
まず、依存関係にあるライブラリのインストールをします。
cmzp の versionによっては動かない可能性あり↓
* Jupyter NotebookにRuby Kernelを追加する方法terminalbrew install automake gmp libtool wget brew install zeromq --HEAD # 1.30以上で動かないとの記事あり brew install czmq --HEAD gem install ffi-rzmq gem install rbczmqirubyのインストールとjupyterへの登録をします。
terminal# irubyのインストール gem install iruby # irubyの登録 iruby register --force最後にjupyter notebookの起動をします。
terminaljupyter notebook以下のように Ruby が New の中に入っているのを確認して下さい。
- 投稿日:2021-02-13T19:48:10+09:00
Rails6 herokuでデプロイ
初めまして
私は、オリアプを作成しており、そのうちの何個かはherokuでデプロイしています。
そこで、herokuでデプロイする方法を備忘録として残したいと思います。環境
Rails6
Ruby2.6.5Herokuを操作します。
まだ、Herokuをインストールしていない方は、どのディレクトリでもいいので下記を実行しましょう。
% brew tap heroku/brew && brew install heroku
Herokuへログインします。
まだ、Herokuの登録ができていない方は、先に登録してくださいね。
# Herokuへログインするためのコマンド % heroku login --interactive => Enter your Heroku credentials. # メールアドレスを入力し、エンターキーを押す => Email: # パスワードを入力して、エンターキーを押す => Password:Heroku上にアプリケーションを作成します。
自身のアプリのディレクトリに移動してください。そこで下記を実行します。
% heroku create アプリ名 #git config --list | grep heroku作成できているか確認できます。Heroku上でDBを使えるようにします。
Heroku上のDBはデフォルトで「PostgreSQL」になっています。
なので、私はローカル環境で「Mysql」を使用していたのでDBの設定を変えます。% heroku addons:add cleardb #ClearDbを追加することで「Mysql」を使用できます。 % heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL` # ClearDBのURLを変数heroku_cleardbに格納します。。 % heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5} #DBのURLを再設定します。Heroku上にmaster.keyを設置します。
Heroku上にmaster.keyを環境変数として設置します。
% EDITOR="vi" bin/rails credentials:edit #credentials.yml.encをmaster.keyによって復号し、中身を確認しておきます。 # 「escキー」「:」「q」で閉じることが出来ます% heroku config:set RAILS_MASTER_KEY=`cat config/master.key` # 本番環境へ設置します。 #heroku config で念のため設定できているか確認しておきます。アプリケーションをプッシュします。
Herokuで「Stack」を指定します。
※Stackはデプロイされたアプリケーションを読み取り正常に動作させるためのもの今回私は「Ruby2.6.5」の為、「heroku-18」を使います。
% heroku stack:set heroku-18 -a ご自身のアプリ名 % git push heroku master # Herokuにプッシュします。Heroku上にマイグレーションファイルを上げます。
Heroku上にもDBを反映させなければ正しく動作しませんので反映させます。
% heroku run rails db:migrate # heroku apps:infoでアプリの情報を見ることが出来ます。上記の設定でアプリを公開することが出来ているはずです!
Heroku上のアプリを削除したい場合
HerokuのWebサイトから削除することが出来ます。
手順として
①削除したアプリを選択
②「Settings」の一番下の「Delete」を押して、アプリ名を入力し削除しかし、削除しただけでは全て消えません。
gitのリモートリポジトリにherokuが設定されたままになっています!
下記を実行します。% git remote rm heroku
最後に
herokuを使えば簡単にアプリケーションの公開ができるのでおすすめです!
ここまで読んでいただきありがとうございました!
- 投稿日:2021-02-13T19:42:40+09:00
【Ruby on Rails】返すデータに制限をかけたりかけなかったりするために、七つのアクション以外を定義するのはやめよう...
なぜ書くか
これまたコードレビューの際にご指摘いただきました。
備忘録と、コツコツとプロの開発者としての思考を身につけるためにアウトプットさせていただきます。脱「動けばいい」精神
まず、前提としては、RailsはApiでのやり取り専用のコントローラ。
iOSアプリケーションからリクエストを受け取り、それぞれのリクエストに応じた処理が実行されます。実際に問題となった機能を実装する前は、コントローラは下記の様な状態でした。(コードは多少変更しています。)
module Api module V1 class ProductController < ::Api::ApplicationController protect_from_forgery except: [:create] def index render json: Product.trader_filter(params[:trader_id]) end def create render json: Product.new(product_params).save end private def product_params params.permit(:name, :price) end end end endしかしここでiOS側でのとあるページの都合で「その日、当日分の商品情報だけ欲しいな...」といったことが発生しました。(なんの当日分かは置いといて)
すかさず、Railsアプリケーションのコードを追加し、書いたコードは下記の様なコードです。module Api module V1 class ProductController < ::Api::ApplicationController protect_from_forgery except: [:create] def index render json: Product.trader_filter(params[:trader_id]) end def create render json: Product.new(product_params).save end def acquisition_of_product_data_on_the_day render json: Product.trader_release_date_filter(params[:trader_id], params[:release_date]) end private def product_params params.permit(:name, :price) end end end endルーティングにコレクションを使用し、七つのアクション以外のアクションを定義し、コントローラでモデルのスコープを呼び出しています。
この時は「もうindexは使っちゃってるしなぁ」と安直にアクションを追加し、これでいいと思っていました。しかし、先輩にレビュー依頼出したところ、ここが指摘されました。
理由としては、検索条件を追加するたびにいちいちアクションを追加していたら、コントローラのメソッドの数がえげつないことになり、いわゆる「fat Controller」になってしまいメンテナンスが難しくなってしまうということでした。
まさに「動くからええやん...」気分で書いたコードでした。
しかし実際に本当にその通りで、検索の内容が変わるたびに「get」のリクエストを増やしまくっていたのでは、いつか維持できなくなります。
「将来的にも追加はそこまでないからいいのでは?」と思ったりもしたのですが、とにかく同じようなメソッドを何個もコントローラーに書くのはスマートではないと。ではどうするか?
本来コントローラは左から右へ処理、命令を流すだけの役割です。
なので、当日分のデータを返したいのかそうでないのか?といったこともコントローラに考えさせるべきではありません。なのでindexで、全体取得、本日分のみの取得のリクエストも受け取り、モデルに判断させます。
module Api module V1 class ProductController < ::Api::ApplicationController protect_from_forgery except: [:create] def index render json: Product.trader_filter(params[:trader_id], params[:release_date]) end def create render json: Product.new(product_params).save end private def product_params params.permit(:name, :price) end end end end最初との違いは、indexメソッドに渡すparamsの中身を追加しただけです。つまり取得したい日付のデータですね。
そしてモデルのスコープは以下のように実装します。
scope :trader_filter, ->(trader_id, release_date) do if release_date.nil? #全件検索の処理 else #当日分のデータ取得の処理 end endこれで、コントローラにアクションを増やすことなく、同じ動きを実現できました。
コントローラから、スコープを見に行くだけで、どのようなデータを返すようになっているかも一発で分かるので可読性もこちらの方が高いと思います。
- 投稿日:2021-02-13T19:07:28+09:00
[Rails]gretelとパンくず(パンくずリストの作り方)
何を書くのか
railsのgem "gretel"を用いたパンくずリストの作り方
環境
Rails: 6.0.3.4
Ruby: 2.6.5結論
gretelの力でパンくずを作成し、それをビューで表示する。
パンくずリストとは
こういう風に、ヘッダーなどに「今どこどこにいますよ!」っていう表示を見た事があるでしょうか。これをパンくずリストと言います。今回は、これを作成していきます。
gretelの導入
今回使うのは、gemのgretelです。
gretelのGithub最初に、gretelの導入を行います。
Gemfileに記述し、bundle installします。
gem "gretel"と、記述し、ターミナルで
$ bundle installを実行します。
そしたらターミナルでこちらのコマンドを実行しましょう。
rails g gretel:installこれを実行すると、"breadcrumbs.rb"というファイルが生成されます。
ファイルの中は、こんな感じになっているかと思います。breadcrumbs.rbcrumb :root do link "Home", root_path end # crumb :projects do # link "Projects", projects_path # end # crumb :project do |project| # link project.name, project_path(project) # parent :projects # end # crumb :project_issues do |project| # link "Issues", project_issues_path(project) # parent :project, project # end # crumb :issue do |issue| # link issue.title, issue_path(issue) # parent :project_issues, issue.project # end # If you want to split your breadcrumbs configuration over multiple files, you # can create a folder named `config/breadcrumbs` and put your configuration # files there. All *.rb files (e.g. `frontend.rb` or `products.rb`) in that # folder are loaded and reloaded automatically when you change them, just like # this file (`config/breadcrumbs.rb`).これが確認できれば、準備は完了です。
breadcrumbs.rbの中身を作る
それでは、ここからはパンくずリストの中身、つまり表示する文字列だったりを決めます。
ここでは、gretelの公式で紹介されている例を参考に説明します。breadcrumbs.rb#トップページ crumb :root do link "Home", root_path end # 一覧表示ページ crumb :issues do link "All issues", issues_path end # 詳細表示ページ crumb :issue do |issue| link issue.title, issue parent :issues end説明を加えます。
breadcrumbs.rblink "Home", root_path基本の型は、'link "表示する文字列", パス'です。それを
breadcrumbs.rbcrumb :root do link "Home", root_path endのように、do~endで囲ってあげます。
ちなみに、:rootは、ビューの表示等で利用することになるので、自分が判断しやすい名称に設定しておきましょう。また、こういうこともできます。
breadcrumbs.rb#詳細表示ページ crumb :issue do |issue| link issue.title, issue parent :issues end詳細表示ページには、parent :issuesとあります。これは、「issuesを親に持つよ!」ということを示しています。
これがないと、ページ間のつながりを判断してもらえず、意味がなくなってしまいます。ビューに表示する
それでは、先ほど作ったパンくずリストの要素等を、ビューで表示していきます。
この例では、app/views/issues/show.html.erbを例にだします。
issues/show.html.erb<% breadcrumbs :issue, @issue> <%= breadcrumbs separator: " › " %> <%# 矢印を示すオプション %>基本的に、表示に必要なのは、この二つだけです。1行目で、(コントローラーから送られてきた)@issueを、先ほどcrumbの後ろにシンボルで記述した:issueのバリューとして定義します。あとは、自由にオプションをつけて、完成です。
補足
これは、初歩中の初歩です。公式Githubにはいろいろなオプションが確認できるので、ここからはそちらを参考してください。
最後に
最後まで読んでいただき、ありがとうございます。
ソースコード、記事の書き方について「もっとこうしたほうがいいよ!」というご意見、「そこどうなっているの?」というご質問など、お待ちしております。参考文献
- 投稿日:2021-02-13T18:10:23+09:00
【Rails】Zeitwork::NameError を解消する
1.はじめに
railsでアプリを作成し、サーバーを立ち上げ
rails s
を行い、http://localhost:3000/XX
にアクセスしました。
すると、Zeitwork::NameError
と表示されました。2.使用環境
・mac.os バージョン10.15.6
・Ruby 2.6.6
・Rails 6.0.3.5
・psql (PostgreSQL) 12.63.実際のエラー
太字に着目するとPostsContrlllerの定義が変という旨が書かれていますね。
4.結論:スペルミスでした
ということで
Postscontroller
クラスの記述をしているposts_controller.rb
を確認すると...posts_controller.rbclass Postcontroller < ApplicationController def index @posts = Post.all end end2箇所も間違えておりました。(下記が正しいものです。)
posts_controller.rbclass PostsController < ApplicationController def index @posts = Post.all end end5.まとめ:スペルミス気をつけます
とは言え、Rails6.0で新たに導入された
Zeitwork
モードについて学ぶ良い機会となりました。6.参考リンク
Railsガイド-定数の自動読み込みと再読み込み (Zeitwerk)
7.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
- 投稿日:2021-02-13T16:42:04+09:00
【Rails】rails s したらAddress already in useのエラーが出たので解消する
1.はじめに
railsでアプリを作成し、サーバーを立ち上げ
rails s
を行い、動作確認を試みました。
すると、Address already in use
と表示されました。私:「
http://localhost:3000
複数立ち上げてないはずだけど...」
複数回このエラーに遭遇したため、備忘録も兼ねてまとめていきます。2.使用環境
・mac.os バージョン10.15.6
・Ruby 2.6.6
・Rails 6.0.3.5
・psql (PostgreSQL) 12.63.実際のエラー
ターミナル.1: from /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.7/lib/puma/binder.rb:229:in `new' /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/puma-4.3.7/lib/puma/binder.rb:229:in `initialize': Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)「Rails Address already in use」などで調べ、エラーの解消を試みました。
4.解決策
① 別のポートを使う
・URLを
http://localhost:3000
→ 例:http://localhost:3001
に変更する
・コマンドをrails s
からrails s -p 3001
に変更するこれでしばらくできていたのですが、数回行った後に同様のエラーが出ていたことと、応急処置的な策だと思い、別の方法を試しました。
② 立ち上がっている別のrailsサーバーを落とす
ps -ax | grep ruby
とコマンドを入力します。
略称 内容 ps process の略。
OS内部で現在実行されているプロセス一覧を表示するax a:端末を持つ全てのプロセスを表示する
x:端末を持たない全てのプロセスを表示するパイプ コマンドの出力結果を次に渡す処理をする grep ファイル中の文字列を検索する ※パイプは
|
のことです。ターミナル.hogehoge@hogenoAir sample_app % ps -ax | grep ruby 13657 ?? 242:21.97 ruby -I /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib -I /Users/hogehoge /.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/spring-2.1.1/lib -e require 'spring/application/boot' 13666 ?? 0:01.28 /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/rb-fsevent-0.10.4/bin/fsevent_watch --format =otnetstring --latency 0.2 /Users/hogehoge/Desktop/sample_app 13667 ?? 0:00.69 /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/rb-fsevent-0.10.4/bin/fsevent_watch --format =otnetstring --latency 0.1 /Users/hogehoge/Desktop/sample_app/config/locales 13669 ?? 0:00.70 /Users/hogehoge/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/rb-fsevent-0.10.4/bin/fsevent_watch --format =otnetstring --latency 0.1 /Users/hogehoge/Desktop/sample_app/db /Users/hogehoge/Desktop/sample_app/app/channels /Users/ hogehoge/Desktop/sample_app/app/controllers /Users/hogehoge/Desktop/sample_app/app/helpers /Users/hogehoge/Desktop/sample_app/app/jobs /Users/hogehoge/Desktop/sample_app/app/mailers /Users/hogehoge/Desktop/sample_app/app/models 68459 ttys004 0:00.00 grep rubyプロセスを確認しrailsサーバーの場合はkillします。
(ない場合は、rails以外の別サービスが3000番ポートを使用していますのでそれを切ります。)killをする場合は、
kill 〇〇
とコマンドを入力します。
※killは実行しているプロセスを終了するコマンドです。〇〇には、PID(プロセス番号)
が入ります。今回は強制終了のシグナル
-9
をつけて、killを行いました。ターミナル.hogehoge@hogenoAir sample_app % kill -9 13657 hogehoge@hogenoAir sample_app % kill -9 13666 kill: kill 13666 failed: no such process hogehoge@hogenoAir sample_app % kill -9 13667 kill: kill 13667 failed: no such process hogehoge@hogenoAir sample_app % kill -9 13669 kill: kill 13669 failed: no such process
13657
のみ反応が返ってきていないものの、他は該当のプロセスはなかったようで、failed: no such process
と怒られました。③ 3000番ポートを使用している他のプロセスを探してkillする
lsof
コマンドを使用します。lsof [オプション] [パス名]
という風に使います。
今回は、lsof -i:3000
とコマンドを入力します。
略称 内容 lsof オープンしているファイルを一覧表示する -i 全てのネットワークソケットを対象にする
※「-i4」でIPv4,「-i6」でIPv6を指定できるターミナル.hogehoge@hogenoAir sample_app % lsof -i:3000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 13924 hogehoge 23u IPv6 0xc40f37229745897b 0t0 TCP localhost:hbci->localhost:54998 (CLOSE_WAIT) ruby 13924 hogehoge 24u IPv6 0xc40f372296a66d3b 0t0 TCP localhost:hbci->localhost:55019 (CLOSE_WAIT) ruby 15604 hogehoge 12u IPv6 0xc40f372296a6735b 0t0 TCP localhost:hbci (LISTEN) ruby 15604 hogehoge 13u IPv4 0xc40f37228ef3cb4b 0t0 TCP localhost:hbci (LISTEN) ruby 15604 hogehoge 23u IPv6 0xc40f372291635d3b 0t0 TCP localhost:hbci->localhost:55859 (CLOSE_WAIT) ruby 15604 hogehoge 24u IPv6 0xc40f372297454c3b 0t0 TCP localhost:hbci->localhost:55879 (CLOSE_WAIT) ruby 15604 hogehoge 30u IPv6 0xc40f372291632c3b 0t0 TCP localhost:hbci->localhost:55904 (CLOSE_WAIT) ruby 15604 hogehoge 35u IPv6 0xc40f37229163261b 0t0 TCP localhost:hbci->localhost:55905 (CLOSE_WAIT) ruby 15604 hogehoge 37u IPv6 0xc40f37229b46e97b 0t0 TCP localhost:hbci->localhost:55911 (CLOSE_WAIT) ruby 15604 hogehoge 40u IPv6 0xc40f37229b46b25b 0t0 TCP localhost:hbci->localhost:55912 (CLOSE_WAIT)
13924
と15604
がヒットしたので、それぞれkillします。ターミナル.hogehoge@hogenoAir sample_app % kill 13924 hogehoge@hogenoAir sample_app % kill 15604再度確認してみます。
ターミナル.hogehoge@hogenoAir sample_app % lsof -i:3000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 13924 hogehoge 23u IPv6 0xc40f37229745897b 0t0 TCP localhost:hbci->localhost:54998 (CLOSE_WAIT) ruby 13924 hogehoge 24u IPv6 0xc40f372296a66d3b 0t0 TCP localhost:hbci->localhost:55019 (CLOSE_WAIT) ruby 15604 hogehoge 12u IPv6 0xc40f372296a6735b 0t0 TCP localhost:hbci (LISTEN) ruby 15604 hogehoge 13u IPv4 0xc40f37228ef3cb4b 0t0 TCP localhost:hbci (LISTEN) ruby 15604 hogehoge 23u IPv6 0xc40f372291635d3b 0t0 TCP localhost:hbci->localhost:55859 (CLOSE_WAIT) ruby 15604 hogehoge 24u IPv6 0xc40f372297454c3b 0t0 TCP localhost:hbci->localhost:55879 (CLOSE_WAIT) ruby 15604 hogehoge 30u IPv6 0xc40f372291632c3b 0t0 TCP localhost:hbci->localhost:55904 (CLOSE_WAIT) ruby 15604 hogehoge 35u IPv6 0xc40f37229163261b 0t0 TCP localhost:hbci->localhost:55905 (CLOSE_WAIT) ruby 15604 hogehoge 37u IPv6 0xc40f37229b46e97b 0t0 TCP localhost:hbci->localhost:55911 (CLOSE_WAIT) ruby 15604 hogehoge 40u IPv6 0xc40f37229b46b25b 0t0 TCP localhost:hbci->localhost:55912 (CLOSE_WAIT)再度表示されたので、
kill -9
でkillします。ターミナル.hogehoge@hogenoAir sample_app % kill -9 13924 hogehoge@hogenoAir sample_app % kill -9 15604 hogehoge@hogenoAir sample_app % [1] - killed rails s hogehoge@hogenoAir sample_app % lsof -i:3000 hogehoge@hogenoAir sample_app %killができたようなので、再度
rails s
でサーバーを起動します。ターミナル.hogehoge@hogenoAir sample_app % rails s => Booting Puma => Rails 6.0.3.5 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.7 (ruby 2.6.6-p146), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://127.0.0.1:3000 * Listening on tcp://[::1]:3000 Use Ctrl-C to stopということで、無事エラーを解決することができました。
5.参考リンク
1:【 ps 】コマンド――実行中のプロセスを一覧表示する
2: rails sが通らない
3:パイプでつないでgrep?: Railsチュートリアル備忘録 - 8章
4:grepコマンドの詳細まとめました【Linuxコマンド集】
5:プロセスを終了するkillコマンドの使い方まとめ!【Linuxコマンド集】
6:【kill】Linuxでプロセスを終了させるコマンド
7:【 lsof 】コマンド――オープンしているファイルを一覧表示する
8:知ったかぶりをしていたソケット通信の基礎を改めて学んでみる6.最後に
記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
- 投稿日:2021-02-13T15:01:04+09:00
【Window限定】Rubyのコードをexe形式で出力する
調べてみたところ、あまり活発ではない手法のようです。
Mac用に書き出せたりもしないので
JavaScriptでElectonとかを使ったほうがスムーズかもしれませんね。ただ、Rubyを使うだけでexe形式の何かを作れるのは良いと思いました。
> ocra .\sample.rbさて、雑に上記のようにしますとexe生成には成功しますが次のようなエラーが発生して起動しません。
ruby_buiktin_dlls\libssp-0.dll was not found
これを解消しなくてはなりません。
> ocra .\sample.rb --dll ruby_builtin_dlls\libssp-0.dllこれで解決です。
次に ocra は sample.rb 実行して依存関係を調べているような気がします。
なので終了しないスプリクトだと処理が終わらないような気がします。そこで --no-dep-run (実行しない) を入れます。
公式に --no-dep-run は --gem-full セットでと書いてあったのでそうします。> ocra .\sample.rb --no-dep-run --gem-full --dll ruby_builtin_dlls\libssp-0.dll最終的な実行コマンドはこちらです。
これで Windows で実行可能な exe形式のruby製プログラムの作成に成功しました。
- 投稿日:2021-02-13T13:32:53+09:00
railsアプリをcapsitranoでdeployする時に自動でseedを実行する。けど必要な時だけする。
本記事のサマリ
capistranoでrailsアプリをdeployする際に、自動的にseedを流すようにすると、deployの運用的には楽になるが、seedの実行時間が待たされるので、seedファイルが描き変わった時だけ動くように工夫するといいかもという話です。
対象読者
- capistranoをつかって、railsアプリをデプロイしており、seedの実行は手動でやっているような方
- seedの実行をcapに任せているが、毎回時間かかっているような方
動作確認バージョン
Capistrano Version: 3.11.2 (Rake Version: 10.3.2) Rails 5.1.6 ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin18]経緯
capistranoでデプロイする際に、seedの実行は変更があったときに、手で実行するのは、面倒です。
なので、そういったものは、自動的にやるようにしたいというのが、怠惰なプログラマな正常な欲求です。
でも、自動的にやってみたのはいいものの、毎回実行していると、seedの肥大化に伴って、実行時間の待ち時間がもったいない。
ならば、seedの変更が会った時だけ実行するようにしようというのが敬意です。方針
やり方はいろいろあると思いますが、seedファイルの変更を検知するために、seedファイルのmd5のハッシュ値をとっておいて、それが切り替わったら実行するというやり方で実現してみました。
実物
以下のように、独自で定義したcapistranoのタスクを、
deploy:migrate
の後で実行するようにします。deploy.rb# 〜中略〜 # deploy用のスクリプトで、migrateの後にdeploy:seedタスクを実行させる after 'deploy:migrate', 'deploy:seed' # 〜中略〜実際に、seedを実行するタスクは以下のようにして、seedファイルのmd5を保持しておき、それを比較して違っていたらseedを実行するような形で実現します。
deploy.cap# 〜中略〜 # seedの実行タスクは以下の通り # 前提となる情報 # release_path: deployされたアプリのパス # shared_path: 別のリリース時でも共有できる共有ディレクトリのパス # seedファイルは、実行されるたびに、トランザクションを貼って洗い替え(delete & insert)することで、冪等性を担保している。 desc 'Load seed data into database' task :seed do on roles(:db) do within release_path do with rails_env: fetch(:rails_env) do command = 'db:seed' # rakeのコマンドを元に、seedファイルの相対パスを組み立て seed_filepath = 'db/seed.rb' new_digest_filepath = shared_path.join("new_#{seed_filepath.gsub('/', '_')}.md5") digest_filepath = shared_path.join("#{seed_filepath.gsub('/', '_')}.md5") # digestがなかった時にエラーにしないために、事前にtouch execute :touch, digest_filepath execute :md5sum, "#{seed_filepath} > #{new_digest_filepath}" # md5が違っていたらseedを反映するコマンドを実行する execute "if [ \"`cat #{new_digest_filepath}`\" != \"`cat #{digest_filepath}`\" ]; then cd #{release_path}; RAILS_ENV=#{ fetch(:rails_env) } bundle exec rake #{command}; mv #{new_digest_filepath} #{digest_filepath}; fi" end end end end end
- 投稿日:2021-02-13T12:56:39+09:00
Rails6.1開発ハンズオン(1)
ターゲット
- Rails、Rubyを全く知らない人
- 何らかのプログラミング言語でコードを書いたことがある人
- ある程度shellの操作に慣れている人
- macがなくてwindowsしかない人
目的
Rails6.1で基本的な機能を雑に触れながらそれっぽいアプリを作る
やること
- Gitの設定
- ログインなしで書き込めるネット掲示板を作る
- ベースはこれを使う + vscodeに拡張機能を入れて開発
1. 開発環境を整える
1-1. vscodeを整える
vscodeをインストールする。
Visual Studio Code - コード エディター | Microsoft Azure
これでWSLに接続して開発できる(これ以降の拡張機能は必要に応じてWSL上にインストールされる。)
Remote - WSL - Visual Studio Marketplace
日本語化
Japanese Language Pack for Visual Studio Code - Visual Studio Marketplace
アイコンをわかりやすく表示
Material Icon Theme - Visual Studio Marketplace
Ruby関連
Ruby - Visual Studio Marketplace
補完とかしてくれる言語サーバ solargraphさん
# solargraphをインストール gem install solargraphRuby Solargraph - Visual Studio Marketplace
endを自動で入れてくれる
endwise - Visual Studio Marketplace
draw.ioを使いたい
Draw.io Integration - Visual Studio Marketplace
1-2. Gitを整える
first commit
git config --global user.email "you@example.com" git config --global user.name "Your Name"github SSH認証の準備
参考にさせていただくもの:
WSL2 から起動した VSCode DevContainer に SSH agent で Git の鍵を渡す - Qiitacd ~ ssh-keygen -t ed25519 -P "" # 何も入れずにEnter cd .ssh more id_ed25519.pub # 内容をコピーBuild software better, together
SSH and GPG keysで「New SSH Key」ボタンを押す。
わかりやすいTitle(WSL2とか)を入力、Keyにコピーした公開鍵を貼り付け、Add~/.bashrcを開いて以下のコードを追加
if [ -z "$SSH_AUTH_SOCK" ]; then # Check for a currently running instance of the agent RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`" if [ "$RUNNING_AGENT" = "0" ]; then # Launch a new instance of the agent ssh-agent -s &> $HOME/.ssh/ssh-agent fi eval `cat $HOME/.ssh/ssh-agent` fi ssh-add $HOME/.ssh/id_ed25519github上にリポジトリを新規作成、(ここでは「Rails6.1_hands_on」という名前)
git remote add origin git@github.com:hirorocky/Rails6.1_hands_on.git git push -u origin master # Rails6.1だとまだ”master”2. 掲示板を作る
2-0. Railsの基礎知識:MVCモデル
詳しくは「Rails MVC」で検索!
私は正しく理解している自信はないですが、こんな図を描いてみました↓
リクエストが来たら、Rails上のroutes.rbがコントローラーとアクション(=メソッド)を決めて、コントローラー上のアクションでモデルからデータを取りながら、ビューを作って、その結果をブラウザに返すイメージです。2-1. 設計
◆モデル図
(拡張機能により、〇〇.drawioというファイルを作ればvscode上でdraw.ioが使える!)
◆ワイヤーフレーム(?詳しくない)
4枚のページが必要そう。
- communities_controller#index:トップページ
- communities_controller#new→#create:コミュニティ作成ページ
- communities_controller#show:1つのコミュニティ&コメント一覧
- comments_controller#new→#create:コメント投稿ページ
なぜこのコントローラー×アクションの組み合わせなのかは聞かないでください。
2-2. 実装
2-2-1. モデル
DB上に各テーブルを作る。
' rails generate model <モデル名> <カラム名>:<型>...'
でモデルに関するファイルを自動で作ってくれる。
rails generateはrails gと省略できる。※以降gで書きます。
rails g model Community title:string owner_name:string rails g model Comment author_name:string content:text community:referencesdb/migrateフォルダ内に、2つのファイル(マイグレーションファイル)ができる。
以下のコマンドでDBにテーブルを作成する。
# sqlite上にRails用DBを作成 rails db:setup # DB上にマイグレーションファイルをもとにテーブルを作成 rails db:migrateapp/models/community.rbにて
class Community < ApplicationRecord has_many :comments endapp/models/comment.rbにて
class Comment < ApplicationRecord belongs_to :community endこうするだけで、RailsのORMがいい感じにしてくれる。
※ちょっと試すにはターミナルでrails console(rails cでも可)コマンド。
irb(main):001:0> commu = Community.create(title: 'コミュニティタイトルです', owner_name: 'たろう') (0.4ms) SELECT sqlite_version(*) TRANSACTION (0.1ms) begin transaction Community Create (0.5ms) INSERT INTO "communities" ("title", "owner_name", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "コミュニティタイトルです"], ["owner_name", "たろう"], ["created_at", "2021-02-13 02:21:28.386695"], ["updated_at", "2021-02-13 02:21:28.386695"]] TRANSACTION (5.0ms) commit transaction => #<Community id: 1, title: "コミュニティタイトルです", owner_name: "たろう", created_at: "2021-02-13 02:21:28.386695000 +0000", updated_at: "2021-02-13 02:21:28.386695000 +0000"> irb(main):002:0> commu.title => "コミュニティタイトルです" irb(main):003:0> commu.comments.create(author_name: 'じろう', content: "コメント\nああああ") TRANSACTION (0.1ms) begin transaction Comment Create (0.5ms) INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["author_name", "じろう"], ["content", "コメント\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:21.103087"], ["updated_at", "2021-02-13 02:26:21.103087"]] TRANSACTION (5.1ms) commit transaction => #<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000"> irb(main):004:0> commu.comments.create(author_name: 'じろう', content: "コメント2\nああああ") TRANSACTION (0.1ms) begin transaction Comment Create (0.5ms) INSERT INTO "comments" ("author_name", "content", "community_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["author_name", "じろう"], ["content", "コメント2\nああああ"], ["community_id", 1], ["created_at", "2021-02-13 02:26:35.918169"], ["updated_at", "2021-02-13 02:26:35.918169"]] TRANSACTION (7.1ms) commit transaction => #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000"> irb(main):005:0> commu.comments Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."community_id" = ? /* loading for inspect */ LIMIT ? [["community_id", 1], ["LIMIT", 11]] => #<ActiveRecord::Associations::CollectionProxy [#<Comment id: 1, author_name: "じろう", content: "コメント\nああああ", community_id: 1, created_at: "2021-02-13 02:26:21.103087000 +0000", updated_at: "2021-02-13 02:26:21.103087000 +0000">, #<Comment id: 2, author_name: "じろう", content: "コメント2\nああああ", community_id: 1, created_at: "2021-02-13 02:26:35.918169000 +0000", updated_at: "2021-02-13 02:26:35.918169000 +0000">]>ログを見ると、rubyのコードをSQLに変換して、DBを操作しているのがなんとなくわかると思います。
ここでは見ませんが、上記コードだけで、DBに1つのcommunityレコードと2つのcommentレコードができています。
2-2-2. Communityのコントローラー・ビュー
◆コントローラー
rails g controller communities index new create show設計段階で必要なコントローラーとビューがわかったので、
上記コマンドを入力。すると色々作成される(いらないものもできてしまう...※この辺は設定でいい感じにできますがここでは触れません)
app/controllers/communities_controller.rbのアクションの中にコードを入れる
class CommunitiesController < ApplicationController def index @communities = Community.all end def new @community = Community.new end def create @community = Community.new(community_params) if @community.save redirect_to communities_path else render :new end end def show @community = Community.find(params[:id]) @comments = @community.comments end private def community_params params.require(:community).permit(:title, :owner_name) end end
@hoge
はインスタンス変数で、この文脈で必要な知識としては、「インスタンス変数はビューに渡せる」ということです。
community_paramsメソッドはStrong Parameterというやつです。セキュリティ的に必要なもので、詳しくはググってください。
◆ルーティング
Rails.application.routes.draw do root to: 'communities#index' resources :communities, only: %i[index new create show] end自動生成されたものは全部削除、ルートをcommunities_controllerのindexアクションに割りあて、resourcesメソッドでcommunities_controller関連のルーティングを一気に作成。
rails routesで設定されているルーティングを見ることができ、またもっと見やすくしたいときは、
ブラウザ上で「http://[::1]:3000/rails/info/routes」で見れる。
◆ビュー
ビュー関連はapp/viewsの中に入っている。
自動で作成されたcreate.html.erbはいらないので削除。
早くhamlを使いたい。一旦、見た目ガン無視の最低限の機能を実装する。
app/views/communities/index.html.erb
<h1>掲示板</h1> <%= link_to 'コミュニティ作成', new_community_path %> <% @communities.each do |community| %> <div> <p><%= link_to community.title, community_path(community) %></p> <p><%= community.created_at %></p> <p><%= community.owner_name %></p> </div> <% end %><% %>の中にrubyのコードを入れることができる。
<%= %>はrubyの評価結果をそのままhtmlに書き出す。
=かそうじゃないかは慣れだと思う。
app/views/communities/new.html.erb
<h1>コミュニティ作成</h1> <%= form_with model: @community do |form| %> <%= form.label :title %> <%= form.text_field :title %> <%= form.label :owner_name %> <%= form.text_field :owner_name %> <%= form.submit '作成' %> <% end %>※form_withは一時期デフォルトがremote: trueだったが、local: trueになった。
app/views/communities/show.html.erb
<h1><%= @community.title %></h1> <% @comments.each do |comment| %> <div> <p><%= comment.author_name %></p> <p><%= simple_format(comment.content) %></p> <p><%= comment.created_at %></p> </div> <% end %>2-2-3. Commentのコントローラー・ビュー
◆コントローラー
rails g controller comments new createapp/controllers/comments_controller.rb
class CommentsController < ApplicationController before_action :set_community def new @comment = @community.comments.new end def create @comment = @community.comments.new(comment_params) if @comment.save redirect_to community_path(@community) else render :new end end private def set_community @community = Community.find(params[:community_id]) end def comment_params params.require(:comment).permit(:author_name, :content) end end◆ルーティング
Rails.application.routes.draw do root to: 'communities#index' resources :communities, only: %i[index new create show] do resources :comments, only: %i[new create] end endrails routesコマンドでこうなる。
Prefix Verb URI Pattern Controller#Action root GET / communities#index community_comments POST /communities/:community_id/comments(.:format) comments#create new_community_comment GET /communities/:community_id/comments/new(.:format) comments#new communities GET /communities(.:format) communities#index POST /communities(.:format) communities#create new_community GET /communities/new(.:format) communities#new community GET /communities/:id(.:format) communities#show◆ビュー
app/views/communities/show.html.erb
<%= link_to '←戻る', communities_path %> <h1><%= @community.title %></h1> <%= link_to 'コメントする', new_community_comment_path(@community) %> <% @comments.each do |comment| %> <div> <p><%= comment.author_name %></p> <p><%= simple_format(comment.content) %></p> <p><%= comment.created_at %></p> </div> <% end %>app/views/comments/new.html.erb
<%= link_to '←戻る', community_path(@community) %> <h1>コメントする</h1> <%= form_with model: [@community, @comment] do |form| %> <%= form.label :author_name %> <%= form.text_field :author_name %> <%= form.label :content %> <%= form.text_area :content %> <%= form.submit '投稿' %> <% end %>app/views/comments/create.html.erbは削除。
2-2-4. Gemfileの変更
左上に出ている表示が邪魔なので、rack-mini-profilerを削除。
デバッグ用にpry-railsを入れる。
source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '3.0.0' gem 'rails', '~> 6.1.2', '>= 6.1.2.1' gem 'sqlite3', '~> 1.4' gem 'puma', '~> 5.0' gem 'sass-rails', '>= 6' gem 'webpacker', '~> 5.0' gem 'turbolinks', '~> 5' gem 'jbuilder', '~> 2.7' # gem 'redis', '~> 4.0' # gem 'bcrypt', '~> 3.1.7' gem 'bootsnap', '>= 1.4.4', require: false group :development, :test do gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'pry-rails' end group :development do gem 'web-console', '>= 4.1.0' # gem 'rack-mini-profiler', '~> 2.0' gem 'listen', '~> 3.3' gem 'spring' end gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]ひとまず完成。
次回(?)見た目をそれっぽく整えるの巻。
- 投稿日:2021-02-13T11:48:21+09:00
Railsポートフォリオ作成 #3 DB設計
こんにちは
今回はDB設計を行いました。(前回記事(#2 画面設計))私は、前職(ホテルの料飲部)における、コミュニケーションの課題を解決するアプリを作っているのですが、今回は、
DB設計を行いました
感じたこと
- 抜け漏れをなくするのがとても大変
今回私にとっては、今までにない数のテーブルが登場したため、マインドマップを使い、抜け漏れがないようにと意識しながら、機能、テーブル、カラムを洗い出しました。
しかし、おそらく抜け漏れがあって、後から泣くことになるだろうなあという感じです。。。- ER図を見やすく構成するのが大変
まず全てのテーブルを書き出し、その後リレーションを考えていってしまったため、最後に見やすく構成し直すという手間が発生してしまいました。
先に考えておくべきでした。。。意識したこと
- 色分け、場所分けで少しでもわかりやすいようにする
- 少しでもリレーションがごちゃごちゃしないようにする
次は、いよいよアプリケーションの雛形を作っていきます
- 投稿日:2021-02-13T11:24:08+09:00
RubyonRailsでRSpecによるテストコード実行手順メモ
初Qiita投稿で緊張しますが、自分用メモなのであんまり気張らずに書くようにします。
RubyonRailsでRSpecを使ってテストコード実行するときの簡単な手順メモです。
間違ってたり足りない部分があったら適宜アップデートします。1. Gemfile内のどこの行でもいいので gem 'pry-rails' を追加する。 ※たいていは一番下に追加
2. Gemfileの group :development, :test do 内に下記2行を追加する。
gem 'rspec-rails'
gem 'factory_bot_rails' ※FactoryBotを使わない場合は不要
3. ターミナルで bundle install を実行してGemを使えるようにする。
4. ターミナルで rails g rspec:install を実行してRSpecを使えるようにする。
5. .rspecファイルに --format documentation を追加してテストのログを見やすくする。
6. ターミナルでrails g rspec:model [モデル名] を実行してモデルの単体テストコード用ファイルを生成する。
7. spec/factories/モデル名.rb というファイルにFactoryBotで生成するデータを記述する。(要詳細化)
8. spec/models/[モデル名]_spec.rb に単体テストコードを書く。(要詳細化)
9. ターミナルで bundle exec rspec spec/models/モデル名spec.rb を実行する。要詳細化にしている部分は記載方法を詳しくメモする必要があるためまた今度・・・。
- 投稿日:2021-02-13T10:41:46+09:00
ActiveResourceを使ってRailsアプリ同士をAPI連携させる
ActiveResourceを使う機会があったので、使い方を備忘録として残します。
ActiveResource とは
簡単に言うと、Railsアプリケーション同士を簡単にAPI連携させる機能です。
フロントとバックを分けて実装したい時に使います。
バック側の実装
実装
apiモードでアプリケーションを作成しています。$ rails new back --api $ cd back $ bin/rails g scaffold bookmark title:string url:string comment:text $ rake db:migrate起動
$ rails sフロント側の実装
実装
DBは使わないのでmigrationを削除しています。
$ rails new front $ cd front $ bin/rails g scaffold bookmark title:string url:string comment:text $ rm -f db/migrate/*モデルクラス (app/models/bookmark.rb) を書き換える。
親クラスをActiveResource::Baseに変えて、連携先にhttp://localhost:3000/を指定しています。app/models/bookmark.rbclass Bookmark < ActiveResource::Base self.site = 'http://localhost:3000/' endGemを追加。
Gemfile gem ‘activeresource'$ bundle install # 起動 $ rails s -p 3001 #ポートは3001に指定動作確認
以上で実装、連携は完了です。
ブラウザで "http://localhost:3001/bookmarks" にアクセスして、いくつかブックマークを追加してみましょう。
<参考>
http://webos-goodies.jp/archives/how_to_use_activeresource_1.html
- 投稿日:2021-02-13T10:28:42+09:00
【Ruby on Rails】データベース操作まとめ(rails db:**)
データベース本体に関する操作
rails db:create
データベースの作成
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)rails db:drop
データベースの削除
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)テーブルに関する操作
rails db:migrate
migrationファイルを実行し、テーブルを作成する(全てのmigrationファイルが対象)
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)- VERSION
指定したバージョン以前のmigrationを全てupに、それより後のmigrationを全てdownにするrails db:rollback
最新のmigrationを1つdownにする
<使用可能オプション>
- STEP
downにするmigrationの数を指定する- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)rails db:migrate:status
migrationの状態を表示する
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopment)rails db:migrate:up
VERSIONオプションで指定したmigrationをupにする
<使用可能オプション>
- VERSION
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)rails db:migrate:down
VERSIONオプションで指定したmigrationをdownにする
<使用可能オプション>
- VERSION
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)rails db:schema:dump
現在のデータベースの状態に合わせて、db/schema.rbを更新する
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopment)rails db:schema:load
db/schema.rbにあわせて、データベースを更新する(migrationファイルを参照しない)
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)レコードに関する操作
rails db:seed
dbディレクトリのseeds.rbファイルを実行し、レコードを作成する
<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopment)rails r ファイルpath例:rails r db/seeds/test.rb
特定のseedファイルを実行し、レコードを作成する
いくつかの操作をまとめた物
rails db:setup
rails db:create
rails db:schema:load
rails db:seed
をまとめた物<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest ※seedはdevelopmentのみ)rails db:reset
rails db:drop
rails db:create
rails db:schema:load
rails db:seed
をまとめた物<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest ※seedはdevelopmentのみ)rails db:migrate:redo
rails db:rollback
rails db:migrate
をまとめた物<使用可能オプション>
- STEP
やり直すmigrationの数を指定する- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)- VERSION
対象のmigrationを指定するrails db:migrate:reset
rails db:drop
rails db:create
rails db:migrate
をまとめた物<使用可能オプション>
- rails_ENV
環境を指定する(デフォルトはdevelopmentとtest)- VERSION
指定したバージョン以前のmigrationを全てupに、それより後のmigrationを全てdownにする補足
rakeとrailsの違い
Ruby on Railsのデータベース操作のコマンドを調べていると、rails ~というものとrake ~というものの2種類が見つかります。
これらは、Railsのバージョン4まででは区別をして使用していた物を、バージョン5より区別がなくなったそうなので、バージョン5以降を使用する場合は、全てrails ~で実行できる、とのことです。schema.rbとは
migrationファイルは、それぞれのテーブルの設計図のような物です。
それに対してschema.rbは、現在のデータベースの構造を表した設計図のような物のようです。
すでに問題なく動いている環境をコピーする場合、migrationファイルではなくschema.rbを元にデータベースを構築した方が間違いの元を減らせる、という風にRailsの公式ドキュメントに記載があります。参考ページ
Active Record Migrations — Ruby on Rails Guides
Ruby on Railsでよく使う rake db コマンドまとめ13選 | caramelCase
- 投稿日:2021-02-13T00:53:53+09:00
Herokuでrakeコマンドが使えない問題を解決:bundler: failed to load command: rake
エラー内容
HerokuにデプロイしたRuby+Sinatraアプリで
heroku run rake db:migrate
コマンドを実行すると、bundler: failed to load command: rake
という内容のエラーが出てマイグレーションできない。エラーが起きた環境
- heroku20
- ruby 2.6.6
原因
- 開発環境でのBundlerのバージョンと、heroku環境でのBundlerのバージョンが違う。
解決方法
開発環境のbundlerのバージョンを確認
$ bundle -vBundler version 2.2.8herokuのbundlerのバージョンを確認
$ heroku run bundle -vBundler version 2.1.4開発環境にbundlerのバージョン2.1.4をインストールする
$ gem install bundler -v 2.1.4herokuのbundlerのバージョンに合わせています。
開発環境でbundle install
$ bundle _2.1.4_ installherokuにデプロイ
$ git add . $ git commit -m "changed bundler version" $ git push heroku masterこれで解決できるはずです!
確認
実際にherokuでマイグレーションしてみる
$ heroku run rake db:migratemigratedという感じに出力されてマイグレーションが成功したことを確認できました!
まとめ
このエラー解決するのに3時間くらいかけてしまいました、、笑
間違ったことを書いてしまっていたらご指摘いただけると嬉しいです!
- 投稿日:2021-02-13T00:23:34+09:00
[Ruby on Rails]編集ページでのエラーメッセージの出し方
自身の失敗を踏まえた備忘録を書いていきます。
エラーメッセージの読み込みの記述
上記の記述は別のファイルでエラー文の繰り返し処理を表した記述になります。
記入すべき所が空欄だったりしたら表示される文章を
エラー文と言います。new.htmlと一緒のエラー文を、
編集ページのedit.htmlでも表示させたい時に書く記述を書いていきます。
(例)
編集ページなのでeditとupdateアクションに定義してある
itemのインスタンス変数を使っていきます。
ここで大事なのはprefixの
item_pathを記述した後のメソッドのpatchです。
PATCH
編集をした情報を送信する際に使用するHTTPメソッドのことです。
editやupdateとややこしい所ですが、
今回のpatchは地味に大事なことなので自分も忘れないように覚えておこうと思います。