20200319のRubyに関する記事は19件です。

【13日目】Ruby(配列,ハッシュ)

はじめに

こんばんは。
Ruby2日目です。
平日の進捗はゆっくりなので、
休みに盛り返していきます。
では、本日のまとめをしたいと思います。

本日の学び

  • progate Ruby2

Ruby

配列

languages = ["日本語","英語","スペイン語"] //インデックスは0,1,2の順
puts languages[1]

each文

languages = ["日本語", "英語", "スペイン語"]
languages.each do |language| #インデックスをそれぞれlanguageとする
  puts "#{language}を話せます" #回答はインデックスの数だけ
                 #この中の変数はこの中でしか使えないので注意
end #忘れないように

ハッシュ

exam = {"subject"=>"Math","score"=>80 } #複数の値をまとめて管理する。{}を使う。
puts exam["subject"] #examのsubjectのみ

exams = [
  {subject: "Math", score: 80},
  {subject: "Science", score: 55}
  ]
puts exams[1][:score]

シンボル

exam = {:subject => :Math, :score => 80} #"の置き換え
exam={subject: "Math", score: 80}
puts exam[:score]

ifハッシュ

exam = {subject: "Math"}
if exam[:score]
puts "#{exam[:subject]}の結果は#{exam[:score]}点です"
else
  puts "#{exam[:subject]}の結果は分かりません" #値が無い場合falseとし、要素を入れない
end

所感

Rubyは上から順に辿ってく感じである気がします。
後でコードを読み返した時に分かりやすい印象を受けました。

明日からの3連休、頑張って平日のスローペースを取り返したいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[HowTo]ActiveStorage/アバター画像を登録&表示

先日、Active Storageを使用してアバター登録機能を実装しましたので、備忘録として以下に手順などをまとめておきます!
皆様の開発に少しでも役立てていただければ幸いです。

Active Storageとは

Active Storageとは、Rails 5.2以降に追加された機能で、ファイルのアップロードを可能にします。
似たような機能でCarrierWaveというものもございますが、こちらは過去に記事にしていたので、
今回はActive Storageを使用することにしました。
https://qiita.com/Tatsu88/items/66374abda7245a006ea0

Active Storageの特徴

ActiveStorageはactive_storage_attachmentsとactive_storage_blobsの2つのテーブルを作成します。
アップロードした情報はこれらのテーブルに格納され、モデルと関連づける必要があります。

完成イメージ

今回はマイページのアバター実装を目指します。
まず、アバター情報がないときは以下のイメージとなります。

マイページ(アバターなし)

demo

登録画面

アバター情報は以下にて、登録します。
demo

上記にてアバター情報を登録するとマイページに表示できるようにします。
demo

下準備

ImageMagickとmini_magickのインストール

Active Storageで画像を加工してから(サイズや色など)アップロードするには別のツールをインストールする必要があります。
ImageMagickという画像変換ツールと、それをRailsから使うためのmini_magickというgemをインストールしましょう。

ImageMagickのインストール

ImageMagickは、コマンドラインから簡単に画像の保存形式の変更などが行えるツールです。
ターミナルで下記のコマンドを実行してください。

ターミナル
$ brew install imagemagick

mini_magickのインストール

続いて、mini_magickをインストールしましょう。
mini_magickは、Gemの一種なので、Gemfileに記載します。

Gemfile
gem 'mini_magick'
ターミナル
$ bundle install

#gemを追加したので、必要に応じてrails sは再接続しましょう

Active Storageのインストール

上記にて下準備ができましたので、早速Active Storageをインストールしましょう。

ターミナル
$ rails active_storage:install

#上記で作成したマイグレーションファイルをマイグレートしましょう。(編集は不要です)
$ rails db:migrate

上記コマンドにて、以下のテーブルが作成され、アップロードした情報はこちらに格納されます。
- active_storage_attachments
- active_storage_blobs

関連モデルの編集

上記にてActive Storageの準備ができましたので、続いて関連するモデルを編集しましょう。
今回は"User"モデルに対して、アップロードされた画像情報を"avatar"として紐付けます。

/models/user.rb
has_one_attached :avatar

view:登録画面

今回は、form_withを使用して情報を登録します。
先ほどモデルに記載した情報をベースに記載します。

view(抜粋)
= form_with model: @user, url: profile_update_user_path ,method: :patch, local:true do |f|
 .form-group
   = f.label :プロフィール写真
   = f.file_field :avatar
#既に画像設定されている場合は、その内容を削除します。
  -if @user.avatar.attached?
   =@user.avatar.purge
 .form-group
   %p.form-group__text--center
   = f.submit '変更する', class: "btn-default btn-red"

view:登録内容表示画面

上記記述にて登録した内容を表示するviewを作成します。
ポイントとしては、アバター画像がある場合とない場合で表示する画像を分けてます。
アバター画像の有無は".attached?"メソッドを使用してます。
nil?やblank?やpresent?を使うとうまくいかないので、ご注意ください。

view(抜粋)
.mypage_top_container
 .mypage_top_container_avator
  .mypage_top_container_avator_main
  -if @user.avatar.attached?
   =image_tag @user.avatar, class:"avatar"
  -else
   =image_tag ("noimage.png"),class:"avatar"

以上で設定したアバター画像を表示することができます!
その他、コントローラやルーティングなど準備は必要となりますが、各自設定によると思われますので、
今回は割愛させていただきます。

参照

Active Storage の概要
https://railsguides.jp/active_storage_overview.html

【Ruby入門】真偽判定present?の使い方をわかりやすく解説
https://www.sejuku.net/blog/66030

[Rails5.2]ActiveStorageの仕組み(図あり)と使ってみてわかったこと
https://qiita.com/eightfoursix/items/a47ce1bd945582f5d808

【Rails】image_tagの使い方を徹底解説!
https://pikawaka.com/rails/image_tag

ActiveStorage で画像を複数枚削除する方法
https://h-piiice16.hatenablog.com/entry/2018/09/24/141510

Active Strageを使用してユーザーのアバターを登録、表示する
https://re-engines.com/2018/03/12/active-strage%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E3%82%A2%E3%83%90%E3%82%BF%E3%83%BC%E3%82%92%E7%99%BB%E9%8C%B2%E3%80%81%E8%A1%A8%E7%A4%BA/

以上となります。最後までご覧いただき、ありがとうございました!
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします!
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インクリメンタルサーチで追加済みユーザーが検索されないようにする

目的

チャットアプリのグループメンバー追加ページを以下の仕様で作成する。
- インクリメンタルサーチでメンバー検索をして登録リストに表示
- 登録リストに表示されたメンバーを登録ボタンで追加リストに登録
- 登録されたメンバーは登録リストに表示されない

問題点

登録されたメンバーが登録リストに表示されてしまう。

考え方

検索されたメンバーのIDが追加リストに登録されたメンバーのIDと重複しない場合のみ表示させれば良い。

コード

before.js
users.forEach(function (user) {
  if (user.id) {
    addUser(user);
  }
})
after.js
users.forEach(function (user) {
  let idNum = document.getElementById(user.id);
  if (user.id && !idNum) {
    addUser(user);
  }
})
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsで、どちらか一方のカラムを入力必須(二者択一)にするバリデーション

はじめに

Ruby on Rails で どちらか一方のカラムを入力必須にするバリデーションについて書きます。

具体的な例をあげると、ユーザーモデルのemailphone、どちらか片方だけに必ず値が入るようにバリデーションします。両方に値が入っている場合もNGです。

要件に合わなかったバリデーション

ググって下記のようなバリデーションを見つけましたが、両方入力した場合にバリデーションを通ってしまうので、要件には合いません。

app/models/user.rb
class User < ApplicationRecord
  # phoneが空ならば、emailを必須にする
  validates :email, presence: true, unless: :phone?

  # emailが空ならば、phoneを必須にする
  validates :phone, presence: true, unless: :email?
end
User.create!(name: "たなか", email: "test@example.com", phone: "08011112222")

=> #<User id: 1, name: "たなか", email: "tanaka@example.com", phone: "08011112222", created_at: "2020-03-19 12:29:20", updated_at: "2020-03-19 12:29:20">

要件にあったバリデーション

要件を満たすために、次のカスタムバリデーションを作成しました。

app/models/user.rb
class User < ApplicationRecord
  validate :required_either_email_or_phone

  private

  def required_either_email_or_phone
    # 演算子 ^ で排他的論理和(XOR)にしています
    # emailかphoneのどちらかの値があれば true
    # email、phoneどちらも入力されている場合や入力されていない場合は false
    return if email.present? ^ phone.present?

    errors.add(:base, 'メールアドレスまたは電話番号のどちらか一方を入力してください')
  end
end
User.create!(name: "たなか", email: "tanaka@example.com", phone: "08011112222")

# => ActiveRecord::RecordInvalid (バリデーションに失敗しました: emailまたはphoneのどちらか一方を入力してください)

User.create!(name: "たなか", email: nil, phone: nil)

# => ActiveRecord::RecordInvalid (バリデーションに失敗しました: emailまたはphoneのどちらか一方を入力してください)

User.create!(name: "たなか", email: "tanaka@example.com", phone: nil)

# => <User id: 2, name: "たなか", email: "tanaka@example.com", phone: nil, created_at: "2020-03-19 13:06:55", updated_at: "2020-03-19 13:06:55">

おわり

普段は論理和 || 演算子 か論理積 && 演算子 ばかりで、^ 演算子は使わないので、上記のコードを思いつくまでに時間をかけてしまいました…!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2サーバで生成した公開キーはどこからどこまでなのか

cat ~/.ssh/id_rsa.pub

コマンドで作った公開キーは、どこからどこまでなのか?

結論

ssh-rsa AAA...
から始まって、

...== ec2-user@ip-000-00-00-000
までが

公開キーです

GitHub で SSH keyを登録するときの参考になればと。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのbootstrap導入(rails)

はじめに

bootstrapを導入する時に手間取ってしまったので、初めて触ってみる人でもわかりやすく、導入手順を一からおさらいします:baby_tone1:超初級編です:baby_tone1:
bootstrapは簡単にgridレイアウトを実現できるので、使えるようになると便利です:information_desk_person_tone1:

① Gemfileの末尾にbootstrapを追加

Gemfile
gem 'bootstrap'

今回はバージョン指定はしません。
この時、compass-railsというgemが追加されてあるとエラーを吐いてしまうので、なくて問題ないようなら削除します。

② gemの更新

terminal
$ bundle install

③ application.cssにbootstrapを導入

app>assets>stylesheet>application.css

application.css
@import "bootstrap";

application.cssをapplication.scssに名前変更

④ application.jsにもbootstrapを適用

app>assets>javascripts>application.js

application.js
//= require bootstrap

⑤ bootstrapを挿入

bootstrapから、好きなデザインを探し、適応させたいビューファイルに挿入します。
bootstrapトップページから、ヘッダーのDocumentation->左にあるCommponentsから探します。

e.g.) 今回は、headerにNavbarを使います。
app>views>layouts>application.html.erb

bootstrap navbar.png

application.html.erb
<header>
  ここにコピーしたコードを貼り付け
</header>

これで$ rails sでサーバーを起動させて該当ページを表示させると、下のようにbootstrapが適用されます。

bootstrap navbar適用後.png

後はエディタのbootstrapをコピーした部分のリンクや表示させたい文字などを調節して完成です!やったね!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スクリプト言語 KINX/ライブラリ(File/Directory)

ライブラリ(File/Directory)

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」でお届けしているスクリプト言語 Kinx。前回の記事で プレビュー・リリースしたぜ と勇み足ぎみに突っ走ったが、マニュアルが整っていないので、やはりなかなか使いづらいに違いない。現時点で参考になるのは以下しかないし、英語なので。

そこでだ、若旦那。

少しだけマニュアル代わりになるように、簡易説明をここに記すことにしましたよ。今回は File と Directory。一番実用的な感じがしたので。

重要:

v0.1.0 ではファイル系のインタフェースが不完全だったので、急遽 v0.2.0 を用意しました。下記の内容は v0.2.0 のものです。v0.1.0 では動作しないものが一部あります。
また、標準入力をサポートしました。リリース内容は下記を参照してください。
* リリース・リスト

ライブラリ

File クラス

File クラスはその名の通りファイルの読み書きをするクラスで、静的メソッドを持つ。また、new File(filename, attr) として個別のファイル・インスタンスを作成することもできる。

静的メソッド

File クラスの静的メソッドは、以下の通り。

メソッド 内容 復帰値(型) 引数 意味
File.load(path) ファイル内容をテキスト形式で一括読込み String path: String 中身を読み込むファイルパス
File.mkdir(path) ディレクトリの作成 1: 成功 path: String 作成するディレクトリ・パス
File.rename(oldname, newname) ファイルパスの変更 1: 成功 oldname: String 変更前のファイルパス
newname: String 変更後のファイルパス
File.unlink(path) ファイルの削除 1: 成功 path: String 削除するファイルパス
File.exists(path) ファイルの存在確認 1: 存在する path: String 確認するファイルパス
File.isDirectory(path) ディレクトリ名かどうかの確認 1: ディレクトリである path: String 確認するファイルパス
File.isSymlink(path) シンボリックリンクかどうかの確認 1: シンボリックリンクである path: String 確認するファイルパス
File.filesize(path) ファイルサイズの取得 Integer path: String 確認するファイルパス
File.filedate(path) ファイル日付の取得 { modified, accessed, creation } path: String 確認するファイルパス
File.setFiledate(path, obj) ファイル日付の設定 path: String 確認するファイルパス
obj: Object { modified, accessed, creation }

File インスタンス

File インスタンスは new で作る。サンプルは以下の通り。

var f = new File(filename, attr);

パラメータは以下の 2 つ。

パラメータ 取りうる値 意味
filename 文字列 ファイル名
attr 以下の値の論理和 オープン属性
File.READ 読込可能
File.WRITE 書込可能
File.NEW 新規作成モード
File.TEXT テキストモード
File.BINARY バイナリモード
  • オープン属性は以下のような感じで指定する。
    • File.READ|File.WRITE ... 追記モードで読み書き可能
    • File.READ|File.WRITE|File.NEW ... 新規作成モードで読み書き可能
    • File.READ|File.TEXT ... テキストモードで読み込み専用

File インスタンスのメソッドは以下の通り。すみません、peekgetchputch は v0.1.0 に含まれていません。。。

メソッド 内容 復帰値(型) 引数 意味
f.load() ファイルの中身を一括読み込み String
f.close() ファイルをクローズ
f.readLine() 一行読み込み String, 0: EOF
f.peek(ms) 入力があるか確認 1: 存在する、0: 存在しない ms: Integer タイムアウト(ミリ秒)
f.getch() 1 文字入力 Integer (取得文字コード)
f.putch(ch) 1 文字出力 ch: Integer 出力文字コード
f.print(...args) 改行文字なしで出力 出力文字数: Integer ...args 表示する要素(可変引数)
f.println(...args) 改行文字付きで出力 出力文字数: Integer ...args 表示する要素(可変引数)

File.open

個別に new した場合は close しなければならない(GC されたら勝手にクローズ自体はされる)が、スコープを決めて自動的にクローズさせたい場合は File.open を使うのがオススメ。スコープを抜けるとその場で自動的にクローズされる。こんな感じ。

File.open("README.md", File.READ, &(f) => {
    var l, n = 0;
    while ((l = f.readLine()).isString) {
        System.println("%4d: %s" % (++n) % l);
    }
});

File.open の内容としては、意味的には次のと概ね同等。

function FileOpen(filename, attr, func) {
    var f = new File(filename, attr);
    try {
        return func(f);
    } finally {
        f.close();
    }
}

Directory

ディレクトリをトラバースするために使う。サブディレクトリを見つけた時に再帰的に潜っていく場合は recursiveWalk、潜っていかない場合は walk を使う。

Directory.walk

Kinx のリポジトリ・フォルダで以下を実行してみるとなんとなくわかるかも("src" ディレクトリがあるので動作する、という意味。存在するディレクトリ名にすればどこでも OK)。

Directory.walk("src", &(name) => {
    System.println(name);
});

Directory.recursiveWalk

次のように実行すると違いがわかるはず("src" 配下にサブディレクトリがある前提)。

Directory.recursiveWalk("src", &(name) => {
    System.println(name);
});

おわりに

先日、昔のツェッペリンのインタビューを読んでみて、新しい何か、自分たちがやりたい何か、をガレージ・レベルからスタートさせてやっていく、ってのは改めて ロックだねえ、と感慨に耽っていました。ビッグになったロックスターたちも、最初は こういうのやりたいんだよ とガレージやクラブからスタートさせてる訳です。夢と希望を忍ばせて。

今あるものに満足せずに、また、今現在提供されているものに満足行かないようなら、文句を言うのではなく自分の手で実現させてしまうのが良いよね。そのアティテュードこそがまさに ロックンロール

まだまだ転がり続けようぜ、相棒。

で、最後はいつものおねだりの時間です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsのformにAjaxを実装する前提

RailsにjQueryを使ったAjaxを適用するために色々調べました。
個人的な備忘録として残します。

configを設定

config/application.rb
require File.expand_path('../boot', __FILE__)

module SampleApp
  class Application < Rails::Application
    config.action_view.embed_authenticity_token_in_remote_forms = true    # 追加
  end
end

コントローラーの変更

class HogesController < ApplicationController
  def hoge
    respond_to do |format|
      format.html redirect_to hoge_path 
      format.js    # ※下
    end
  end
end

※ renderで指定しなければアクション名.js.erbを探す

テンプレートの変更

form_withを使っている場合(推奨)

remoteはデフォルトでtrueのでやることなし
(falseにしたい場合はlocal: trueを追加)

app/view/hoges/hoge.html.erb
<div id="ajax-test">
  <%= form_with ... do |f| %>
    <%= f.submit "hogehoge" %>
  <% end %>
</div>

form_for, form_tagを使っている場合、

オプションにremote: trueを付ける。

app/view/hoges/hoge.html.erb
<div id="ajax-test">
  <%= form_for ..., remote: true do |f| %>
    <%= f.submit "hogehoge" %>
  <% end %>
</div>

コントローラーでrenderしなかった場合、以下の点に注意してファイル.js.erbを追加
・適用したいテンプレートと同じ場所に配置
・ファイル名はコントローラーのアクション名と同じ名前に設定

app/view/hoges/hoge.js.erb
$("#ajax-test").html("<%= 'さあ、遠慮なく私をhogeりなさい!' %>");

記述はjQueryで。

.html("...");の部分を

.html("<%= escape_javascript(render('hoges/hoge')) %>");
.html("<%= j ( render('hoges/hoge') ) %>");でも可
などとすると色々できる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails チュートリアル学習記録 第6章

第4、5章については特に書く内容がなかったため学習記録は付けませんでした

6.1

特になし

6.2

特になし

6.3

heroku run rails db:migratebash: heroku: command not foundというエラーメッセージ。
3章の時と同じ方法で解決
nvm install node
npm install -g heroku-cli
を実行後、あらためてheroku run rails db:migrateを実行

6.4

特になし

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyの例外処理まとめ

そもそも例外とは?

プログラム実行中に発生したエラーの意。
例外処理を記述しないと、例外発生時点でプログラムが停止してしまい、それ以降に記述してあるコードが読み込まれない。
Rubyで例外を補足するためにはrescueメソッドを用いる。

例外の種類

Ruby公式リファレンスを参照。

begin~rescueメソッド

例)「1/0」の箇所で、整数は0では割れないため、「ZeroDivisionError」という例外が発生。

begin
  1/0
rescue => e
  puts e
end

#=> divided by 0

eには例外オブジェクト(ZeroDivisionErrorなど)が代入されるので、それら例外オブジェクトに実装されている基本的なメソッドを使用することができる。
- class : 例外の種類
- message : 例外のメッセージ
- backtrace : 例外発生の位置情報

begin
  1/0
rescue StandardError => e
  puts e
  puts e.class
  puts e.class.superclass
  puts e.message
end

#=> divided by 0
#=> ZeroDivisionError
#=> StandardError
#=> divided by 0

応用メソッド(ensure/retry/raise/File.open)

ensure:例外の有無に関わらず実行される

begin
  1/0
rescue => e
  puts e
ensure
  puts "ensure"
end

#=> ensure

retry:beginからの実行をもう一度やり直す

count = 0
begin
  1/0
rescue
  p count += 1
  retry if count < 3
  puts "failed"
end 

#=> 1
#=> 2
#=> 3
#=> failed

raise:意図的に例外を起こす

begin
  raise
  rescue
    p "例外です"
end

#=> 例外です
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ウェブサービスの主な機能について

主な機能一覧

ユーザー管理

1.ユーザー登録機能
2.ログイン機能
3.ログアウト
4.プロフィール登録
5.プロフィール編集
6.退会
7.パスワード変更
8.パスワードリマインダー
9.管理者ユーザー登録

コンテンツ管理

10.コンテンツ登録
11.コンテンツ編集
12.コンテンツ削除
13.コンテンツ一覧表示
14.コンテンツ詳細表示
15.コンテンツ検索
16.お気に入り登録
17.決済

基本的には上記の機能を実装し、そこに追加で機能を付け足していくことでほとんどのウェブサービスを作ることが可能になる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails/Ruby】クラスメソッドとインスタンスメソッドの使い分け

「クラスメソッドとインスタンスメソッドの使い分けについて教えてください」
って前に聞かれてちょっと困ったことを思い出したのでまとめてみました~???

※クラス・インスタンスの概念の説明やクラスメソッド・インスタンスメソッドの詳しい説明は端折ってます~!

クラスメソッド

・クラスに対して使う
 例:newメソッド/など

# インスタンスの生成
Animals.new

・DBからデータを取得したり保存するときに使う
 例:allメソッド/findメソッド/createメソッドなど

# 引数に一致するデータをDBから取得する
User.find(1)

・外部ファイルやサイトからデータを取得する(データを取得し、インスタンスを作成する)ときに使う
 例:スクレイピングなど

・全体で扱うべき情報を扱うときに使う
 例:投稿の総数など

インスタンスメソッド

・生成した個々のインスタンス(投稿1つ1つ、ユーザー1人1人など)に対して使う
 例:update/destroy/eachなど

# userにインスタンスを代入
user = User.find(1)
# userに代入したデータを削除する
user.destroy

最後に

個人的にわかりやすいと思ったクラスとインスタンスの説明で終わります~!

クラス = 野菜という大枠

インスタンス = ニンジン・オクラ・ブロッコリーなど細かな種類

クラスとインスタンスの概念って理解するのってやっぱり難しいですね?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Hashの先頭からn個をとりだす

データを抽出してchartkickに渡すHashに対し、先頭n件を抽出したかった。
helperに以下のメソッドを作成。

def chart_limit(hash, limit=5)
  # Hash[*hash.to_a.shift(limit).flatten!]
  # コメントを受けて以下に変更。
  hash.take(limit).to_h
end
利用例
hash = {"男性40代"=>13, "女性40代"=>6, "女性30代"=>5, "男性60代"=>4, "男性30代"=>4}
p chart_limit(hash, 3)
#=> {"男性40代"=>13, "女性40代"=>6, "女性30代"=>5}

ruby 2.6.5で確認済み。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLインジェクションを回避して、SQL内のカラムを動的に変える

概要

①飲食店クラスがあって、ランチの時間帯とディナーの時間帯を絞り込むメソッドがある
②内部的には、引数に始まりの時間と終わりの時間を受け取って、その条件に合うレコードを取得する
③両者はロジックがほぼ一緒で、違うのはwhere句内のカラムだけ
④同じロジックは書きたくないので、なるべく共通化させたい!

# 飲食店クラス
class Restaurant < ApplicationRecord
  # 飲食店のランチの時間を絞り込むメソッド
  scope :where_by_between_lunch_time, lambda { |start_date, end_date|
    if start_date.present? && end_date.present?
      where('lunch_time BETWEEN ? AND ?', start_date, end_date)
    elsif start_date.present?
      where('lunch_time >= :date', date: start_date)
    elsif end_date.present?
      where('lunch_time <= :date', date: end_date)
    end
  }

  # 飲食店のディナーの時間を絞り込むメソッド
  scope :where_by_between_dinner_time, lambda { |start_date, end_date|
    if start_date.present? && end_date.present?
      where('dinner_time BETWEEN ? AND ?', start_date, end_date)
    elsif start_date.present?
      where('dinner_time >= :date', date: start_date)
    elsif end_date.present?
      where('dinner_time <= :date', date: end_date)
    end
  }
end

対策① 引数の検証を行うように

まず、調べていくとカラムを動的に変えようとするとSQLインジェクションの恐れがあることに気付く。
(SQLインジェクションがわからない方はこちらを参考に)

なのでSQLインジェクションにならないように、最初はこの記事を参考に引数の検証を行うように変更!

# 飲食店クラス
class Restaurant < ApplicationRecord
  ALLOWED_COLUMNS = %w(lunch_time dinner_time).freeze

  scope :where_by_between_date, lambda { |column, start_date, end_date|
    # 定数で予め受け取る想定のカラム名を定義して、それ以外が来たらエラー
    unless text.in?(ALLOWED_COLUMNS)
      raise ArgumentError, "Invalid argument: #{column}"
    end

    if start_date.present? && end_date.present?
      where("#{column} BETWEEN ? AND ?", start_date, end_date)
    elsif start_date.present?
      where("#{column} >= :date", date: start_date)
    elsif end_date.present?
      where("#{column} <= :date", date: end_date)
    end
  }
end

確かに、これだと良さそう・・・

しかし、これにしてもBrakemanで怒られてしまう。。。
(Brakemanは、簡単に言うとRailsアプリケーション内のセキュリティをチェックしてくれるGemです)

対策② サニタイズ処理をする

そんな中、Railsのドキュメントを見ているとquote_column_nameというメソッドを発見!
使えそう!!

ふむふむ。SQLインジェクションにならないようにサニタイズをしてくれるメソッドっぽい。

# 飲食店クラス
class Restaurant < ApplicationRecord
  scope :where_by_between_date, lambda { |column, start_date, end_date|
    # sqlインジェクションにならないようにサニタイズ処理をする
    sanitized_column = ActiveRecord::Base.connection.quote_column_name(column)

    if start_date.present? && end_date.present?
      where("#{sanitized_column} BETWEEN ? AND ?", start_date, end_date)
    elsif start_date.present?
      where("#{sanitized_column} >= :date", date: start_date)
    elsif end_date.present?
      where("#{sanitized_column} <= :date", date: end_date)
    end
  }
end

これだとBrakemanで怒られなくなったし、カラムを動的に変えることができるようになった!!

リファクタ

ここからはリファクタ対応。

元々はこのwhere_by_between_dateにカラム名を第一引数に渡す想定だったけど、
今後呼び出される側のロジックが変更される可能性も想定して、抽象scopeに変更。

# 飲食店クラス
class Restaurant < ApplicationRecord
  # 抽象スコープ
  scope :where_by_between_date, lambda { |column, start_date, end_date|
    # sqlインジェクションにならないようにサニタイズ処理をする
    sanitized_column = ActiveRecord::Base.connection.quote_column_name(column)
    if start_date.present? && end_date.present?
      where("#{sanitized_column} BETWEEN ? AND ?", start_date, end_date)
    elsif start_date.present?
      where("#{sanitized_column} >= :date", date: start_date)
    elsif end_date.present?
      where("#{sanitized_column} <= :date", date: end_date)
    end
  }

  # 下記スコープで抽象スコープを呼び出す形に
  scope :where_by_between_lunch_time, lambda { |start_date, end_date|
    where_by_between_date(:lunch_time, start_date, end_date)
  }

  # 下記スコープで抽象スコープを呼び出す形に
  scope :where_by_between_dinner_time, lambda { |start_date, end_date|
    where_by_between_date(:dinner_time, start_date, end_date)
  }
end

これだとメソッド名も直感的なのでよりわかりやすくなったし、
なにより今後の変更にも強くなった気がする!

追記

対策③ ActiveRecordのメソッドを使う

ご指摘ありがとうございました!

よく考えれば、そもそも生SQLに埋め込まないでActiveRecordのメソッドを使えば問題なかったですね:sweat:

難しく考え過ぎていました。。。

(まあ、でもRailsのサニタイズ処理に関して勉強になったのでヨシ)

# 飲食店クラス
class Restaurant < ApplicationRecord

  START_DATE_INFINITY = '1000-01-01'
  END_DATE_INFINITY = '3000-01-01'

  # 対象のテーブルで不明なcolumnにはUndefinedColumnが出る
  scope :between_date, lambda { |column, start_date, end_date|
    if start_date.present? && end_date.present?
      where(column => start_date..end_date)
    elsif start_date.present?
      # end_dateが無いなら、遠い未来までの範囲
      where(column => start_date..END_DATE_INFINITY)
    elsif end_date.present?
      # start_dateが無いなら、遠い過去までの範囲
      where(column => START_DATE_INFINITY..end_date)
    end
  }
end

おまけ

現在、Float::INFINITYは範囲指定の終わりにしか使用できないんですよね。(Rubyのバグ)

ですが、、、issueにこのように書いてありました!

Ruby 2.6 supports endless range, and ruby 2.7 will support beginless range.

つまり今後リリースされるであろう、Ruby2.7だと始まりに対してもInfinityを使えるようになるみたいです!

その際はこんな感じで書けますね!

# 飲食店クラス
class Restaurant < ApplicationRecord
  scope :between_date, lambda { |column, start_date, end_date|
    if start_date.present? && end_date.present?
      where(column => start_date..end_date)
    elsif start_date.present?
      where(column => start_date.to_time..Float::INFINITY)
    elsif end_date.present?
      # 2.7以降使用できる
      where(column => -Float::INFINITY..end_date.to_time)
    end
  }
end

こっちの方が個人的には綺麗に見えるけど、可読性は微妙かな・・・

[参考記事]
https://qiita.com/jnchito/items/e3a144b07f578cda5ee2
https://www.kagoya.jp/howto/network/sql-injection/
https://api.rubyonrails.org/v4.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html
https://bugs.ruby-lang.org/issues/12961

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

bootstrap3から4への移行方法について (Rails5)

今回はbootstrapのバージョン変更について書いていきたいと思います。

経緯はこうです。ポートフォリオ製作の中、週一の専用メンタリングがあり時間もわずかのところでメンターの方から

 

『あれ?bootstrapは3を使ってるんですね!』

 

な、なんだ!? 教材を参考にして制作を進めてるからそもそもバージョンにこだわりがなくてbootstrap3になっていたわけだが何かまずいのかな?と聞いてみると

 

『今はbootstrap4が主流ですね。特にこだわりがなければ新しいのを使った方がいいですよー。あとは今であれば困ったときにbootstrap4の方が似たようなケースも多いと思うので解決しやすいですよ!!』

なるほど。そしたらどうせ今後も使う機会もあると思うので新しいbootstrap4にバージョンを変更しよう!!

と意気込み、以下の記事を参考にしながらやってみました。

https://qiita.com/NaokiIshimura/items/c8db09daefff5c11dadf

なんだー簡単じゃんと思い いざアプリを立ち上げると

 

 

全然導入できねえ

 

こんなにバージョン更新が難しいとは。。。

やったこと

gemfile中に以下を記述しbundle install

gem 'bootstrap', '~> 4.1.1'
gem 'jquery-rails'  

sprockets-railsがv2.3.2.以上である必要があるらしいので以下コードでバージョン確認

$ bundle show |fgrep sprockets-rails
  * sprockets-rails (3.2.1) 問題なし

app/assets/stylesheets/application.scssの中に@import "bootstrap";があることを確認。またファイル名がcssのままだとよくないのでscssに変えておく
ここも今までのbootstrap3導入まででやっていたことなので問題なし。

 

ブートストラップJavaScriptはjQueryに依存しています。Rails 5.1以降を使用している場合は、jquery-railsgemをGemfileに追加します。

gem ' jquery-rails ' ここもbootstrap3導入まででやっていたことなので問題なし。

application.jsに以下を記述する。

//= require jquery3
//= require popper
//= require bootstrap-sprockets

rails s を再度して立ち上げる

エラー発生

ブートストラップエラー.png

内容をググりながらみていくと
Sass::SyntaxError in Pages#index
シンタックスエラーなのでコンパイルがうまくいってないのかな?

念のため他のページで読み込んでみるも特にエラー内容は変わらず

File to import not found or unreadable: bootstrap-sprockets.
この一行で検索をかけると

http://geekday.hatenablog.com/entry/2017/03/31/021052

同じような境遇の方がいたので早速みてみるも解決せず
タイポもなさそうだしバンドルインストール後railsサーバー再起動するも変わらずエラー

https://github.com/twbs/bootstrap-rubygem

bootstrap4の公式手順を見るも特にやってないことはないんだけどなあと途方に暮れました。まじで

 

 ここから解決方法!!!

というわけでメンターの方に助けを求めると

まずGemファイル内のgem 'bootstrap-sass'を削除した方がいいと
これはbootstrap3を導入するときの記述なので本質的なエラーとは関係ないかもしれないが余計な影響があるかもしれない

 

このエラー画像の下の赤いラインなんですが

@import "bootstrap-sprockets";

app/assets/stylesheets/application.scssの中にbootstrap3の名残で書いていたのですが、これがそもそもbootstrap4では必要がないらしいです なのでこれを削除

@import "bootstrap-sprockets"; File to import not found or unreadable: bootstrap-sprockets.とエラーメッセージが出ているのでこちらのファイルがないのに読み込みにいってます。 なので余談ですがapp/assets/stylesheets/application.scssの中に適当なファイル名を追記すると同じエラーが出ました。(@import "aaaaa";実際にこんなファイルはないので読み込めないですと表示されます) 

再度railsサーバー再起動すると無事に表示!!
3から4に変えたことでデザインは崩れていましたが。

そもそも

 いやーここまで長かった。スタックオーバーフロウの英語の記事もGoogle先生に翻訳してもらいながら他の関係ありそうな記事を何件も読み半日以上格闘してました。
今回も残念ながら一人での解決はできませんでしたが惜しいところまで来ていたかと思います。

 

今後のエラー解決方法としては

バージョンを変える場合は以前のバージョンと更新したいバージョンの公式説明を読んでみる
これに関しては4の導入説明は読んでいたけど3の導入説明は探していなかったので3の記事を読んでいたら導入方法の違いがわかってもしかしたら解決できたかもしれません。更新手順を進める前にgitにpushしてからいろいろ変更しても大丈夫なようにすれば気軽に怪しい場所を削除して解決できるかなと思いました。

 

ニッチではありますが同じ境遇で同じエラーで困っている方は是非参考にしてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ec2をターミナルで操作するときに詰まった話(fatal: Could not read from remote repository.)

(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
を参考に、AWSにrailsアプリをあげようとしていたときの凡ミスについて。

エラー箇所について

上記の記事で

[~]$ ssh mumu_key_rsa

でログインした後に、

[ユーザー名|~]$ vim .gitconfig

で、諸々の設定を記述するところがある。

そこで、記事通り、下記のように設定すればよかった。

[user]
  name = your_name (#gitに登録した自分の名前)
  email = hoge@hoge.com (#git登録時の自分のメアド)

[alias] (#これはお好きに)
  a = add
  b = branch
  ch = checkout
  st = status

[color] (#色付け)
  ui = true

# githubの場合
[url "github:"] (#pull、pushのための設定)
    InsteadOf = https://github.com/
    InsteadOf = git@github.com:

しかしながら、筆者は

[user]
  name = your_name (#gitに登録した自分の名前)
  email = hoge@hoge.com (#git登録時の自分のメアド)

[alias] (#これはお好きに)
  a = add
  b = branch
  ch = checkout
  st = status

[color] (#色付け)
  ui = true

# githubの場合
[url "github:"] (#pull、pushのための設定)
    InsteadOf = https://github.com/(ここに実際にcloneしたいアプリのレポジトリURLを書いていた)
    InsteadOf = git@github.com:(ここに実際にcloneしたいアプリのレポジトリURLを書いていた)

上記を見ていただければ分かる通り、無駄にレポジトリURLを記載してしまっていた。
その結果、git cloneで

fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

と、言われてしまったのだった。

まとめ

(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで

この記事では、丁寧にコメントでここには○○を記述などと書いてくれている。

それをちゃんと読んでいなかった筆者は簡単な設定ミスで結構苦労した(3時間も使ってしまった)。

みなさんが、そして未来の自分が再びこんな凡ミスを犯さないためにも、備忘録的に書かせていただきました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

マイグレーション操作

はじめに

「Ruby on Rails 5 速習実践ガイド」の本の内容(Chapter4-1)に沿ってまとめと、他に調べて知ったことも書いてみようと思います。
(内容薄いですが、、、、)

Ruby on Rails 5 速習実践ガイド(Chapter4-1)

?マイグレーションの適用

2つのステップ

マイグレーションは基本的に2つのステップで行います。
1. Rubyのコードで、データベースのスキーマを変更するファイル、 「マイグレーション」ファイル を作成する
2. rails db:migrate コマンドで、作成した「マイグレーション」ファイルをデータベースに適用する

1つのマイグレーションは1つのバージョン

1つのマイグレーション(ファイル)が、 1つのバージョンとして、扱われます。
マイグレーションファイルを作成しただけでは、データベースは変更されず(バージョンは上がらず)、マイグレーションファイルを適用するとデータベースが変更されます。
マイグレーションを取り消す(バージョンを下げる)にも、マイグレーションファイルを削除するだけでは変更されないため、取り消すコマンドを実行して、操作を適用します。

?バージョンの上げ下げ

下のマイグレーションファイルは、Userテーブル作成し、nameカラムとemailカラムを持つことを記述されています。
changeメソッドの中に、「Userテーブルを作成する」というコードが書かれていれば、
マイグレーションの適用を取り消す際には、「Userテーブルを削除する」というコードが書かれているかのように処理をしてくれます。

db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

こちらのマイグレーションファイルは、nameカラムに入る文字列の長さを制限しています。
upメソッド にバージョンを上げる処理、 downメソッド にバージョンを下げる処理を記述しています。

db/migrate/[timestamp]_change_users_name_limit10.rb
class ChangeUsersNameLimit10 < ActiveRecord::Migration[6.0]
  def up
    change_column :Users, :name, :string, limit: 30
  end

  def down
    change_column :Users, :name, :string
  end
end

?schema.rbについて

Railsは、データベースの構造(スキーマ)を db/schema.rb というファイルに自動で出力します。
テーブル、カラムの構造を確認できます。

Railsガイドには、このように書かれています。

Railsのマイグレーションは強力ではありますが、データベースのスキーマを作成するための信頼できる情報源ではありません。
信頼できる情報源は、やはりデータベースです。Railsは、デフォルトでデータベーススキーマの最新の状態のキャプチャを試みるdb/schema.rbを生成します。

?主なコマンド

migrationまわり

migrationに関する主なコマンドまとめです

コマンド           意味
bin/rails db:migrate 最新までマイグレーションを適用する
bin/rails db:migrate VERSION=20200319 特定のバージョンまでマイグレーションが適用されていた状態にする
bin/rails db:rollback バージョンを1つ戻す
bin/rails db:rollback STEP=2 バージョンを指定したステップ数だけ戻す
bin/rails db:migrate:redo バージョンを1つ戻してから1つ上げる
bin/rails db:version     現在の適応されているバージョンを表示する

dbコマンド

主なdbコマンドも少しまとめてみました

コマンド 意味
bin/rails db:create データベースが作成される
bin/rails db:drop データベースの削除される
bin/rails db:reset db:dropし、db/schema.rbにもとづいてデータベースを作り直す

おしまい

↓こちら参考にしました?
Ruby on Rails 5 速習実践ガイド
Railsガイド
rake or rails コマンドでdbを扱うときのメモ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails6 Action Text アップロードされた画像のファイル名と画像サイズを非表示にする方法

こんにちは、「おすし」です。

最近ぶろぐを始めようと思い、 Action Txet を Rails6 で使おうと思い、導入までは順調だったのですが、いざ画像をアップロードすると、、、

スクリーンショット 2020-03-18 18.33.49.png

なんとアップロードした画像の下にデフォルトでファイル名と画像サイズが表示されています!!!!

解決方法は....Action Textを導入した時に自動的に作成されたこのファイルから...↓

views/activestorage/blobs/_blob.html.erb

<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
   <% if blob.representable? %>
      <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
    <% end %>


    <figcaption class="attachment__caption"> 
      <% if caption = blob.try(:caption) %>
        <%= caption %>
      <% else %>
        <span class="attachment__name"><%= blob.filename %></span>
        <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
      <% end %>
    </figcaption>
 </figure>

figcaptionタグ含め、ネストされているコードを全て消します。

views/activestorage/blobs/_blob.html.erb

<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
   <% if blob.representable? %>
      <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
   <% end %>
</figure>

これだけ!

見てくださりありがとうございます。
それでは、お体ご自愛ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails 削除関連まとめ

1. はじめに

アプリの作り始めに、「なんか気に入らないから1回削除して一から作り直したい」と思ったことはありませんか?
私はあります。そんな時に必要になる操作をまとめました。
すでにアプリを作りこんでいる場合は、削除して作り直すわけにもいきませんから変更の方法を探してみてください。

自分の環境

  • ruby 2.6.5
  • Rails 6.0.2
  • macOS Catalina 10.15.3

2. アプリの削除

アプリの削除をするにはアプリのフォルダを削除すればいいのですが、その前にデータベースを削除しておきましょう。
同じ名前でアプリを作り直したりしたときに以前のデータベースを利用してしまい、不具合が起きる可能性があります。
アプリケーションフォルダ内で、

$ rails db:drop

これでデータベースが削除されます。
そのあとは、以下コマンドでアプリフォルダを削除してもいいですし、ゴミ箱へと放り込んでもいいでしょう。

$ cd .. (1つ上のフォルダへ)
$ rm -rf [アプリ名]

ちなみに上記コマンドの意味は、

  • rm = 削除するというコマンド
  • -rf = ファイルでなくフォルダを削除するよという -r と「」というメッセージ表示はいらないよという -f の 組み合わせ
  • . = 現在のフォルダ

3. コントローラの削除

アプリケーションフォルダ内で以下のコマンドを実行します。
作成の際のrails generaterails gと省略できますが、destroyは出来ません。
ルーティングは自分でconfig/routes.rbをいじって消しましょう。

$ rails destroy controller [削除したいコントローラ名]

4. モデルの削除

マイグレーションを実行する前か後かで操作が変わるので注意。マイグレーション実行というのは、言い換えればデータベースにテーブルを作ること、もしくはrails db:migrateを実行することです。わからなかったら実行後の操作をしてみてください。

マイグレーション実行前

アプリケーションフォルダ内で以下のコマンドを実行します。
作成の際のrails generaterails gと省略できますが、destroyは出来ません。

$ rails destroy model [削除したいモデル名]

マイグレーション実行後

まずはマイグレーションまでしてみましょう。以下コマンドを実行。
説明の都合上、2つのモデルを作ってマイグレーションします。(なんの情報も持っていないモデルだけど気にしない。本当はカラム名:データ型を後ろにつけます)

$ rails g model user ← モデル作成
$ rails db:create ← データベース作成(まだデータベースを作っていない場合)
$ rails db:migrate ← テーブル作成

$ rails g model post
$ rails db:migrate (ここでやるから先の rails db:migrate はやらなくてもいい)

モデルを削除する際には、データベースにテーブルが作成されてしまっているのでそちらを削除してからモデルを削除する必要があります。

まずは以下コマンドを実行してみましょう。

$ rails db:migrate:status

マイグレーションを実行した一覧が出てきます。これが

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200318134652  Create users
   up     20200318134702  Create posts

Statusがupになっているということはこのマイグレーションが実行されている(テーブルが
作られている)ということ。

以下コマンドのどれかを実行して、削除したいモデルのマイグレーションを取り消しましょう。

$ rails db:rollback (1つだけ前の状態に戻す)
$ rails db:rollback STEP=2 (2つ前の状態に戻す)
$ rails db rollback VERSION=20200318134652
  (Migration ID:20200318134652のマイグレーションまで実行された状態に戻す)

マイグレーションが2つくらいならrails db:rollbackを2回やればいいですが、たくさん戻したいならステップ数やバージョンを指定すると楽ですね。(不整合が起きるため、過去の特定のマイグレーションだけを取り消すことはできません。)

これで実行したマイグレーションが取り消されたので、あとはマイグレーション実行前と同様にrails destroy [モデル名]で削除しましょう。

マイグレーション取り消しの前にモデルを削除してしまった場合

せっかちで先にrails destroy [モデル名]を実行してしまった人のため。
例えば先の例でpostモデルを削除してしまったとします。するとpostのマイグレーションファイルも削除されてしまいrails db:rollbackでマイグレーションを取り消すことすらできなくなります。(絶望)

その場合は、まず以下コマンドで新しくマイグレーションファイルを作成します。

$ rails g migration [マイグレーション名]

マイグレーション名はなんでもいいですが、わかりやすくdrop_postとでもしておきましょう。

するとdb/migrate/内に以下ファイルが作成されます。

20200318143822_drop_post.rb
class DropPost < ActiveRecord::Migration[6.0]
  def change
  end
end

changeメソッド内に以下の様に追記しましょう。

20200318143822_drop_post.rb
class DropPost < ActiveRecord::Migration[6.0]
  def change
    drop_table :post
  end
end

そしてマイグレーションを実行します。するとpostテーブルが削除されているため一件落着。

$ rails db:migrate

無駄なマイグレーションファイルが残ってしまうのが自分的に嫌です。ファイルを削除しても問題ないけどrails db:migrate:statusで表示される履歴の中にはしっかり残っています。(※マイグレーションファイルは削除しない様にしましょう)

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200318145751  Create users
   up     20200318150431  ********** NO FILE **********
   up     20200318150544  ********** NO FILE **********

5. scaffoldで作成したモデルやコントローラ等の削除

rails g scaffold [モデル名] カラム名:データ型 (カラム名:データ型...)でモデルやコントローラやルーティングなどを一括作成してくれます。詳しくは別記事を参照してください。

rails g scaffoldで作成したんだからもちろん削除は以下コマンド。全部スッキリ削除してくれます。

rails destroy scaffold [モデル名]

6. データベース内のデータを削除

モデルやコントローラ、ビューなどを作成し、色々試していているとデータベース内のデータがごちゃってきて初期状態に
戻したい時があると思います。そういうときは以下コマンドを実施。

rails db:reset

今あるデータベースを削除して新しくもう一度作ってくれます。db/seeds.rbを使って初期データ投入を行っている場合は初期データ投入も同時にやってくれるので、自分でrails db:seedを行うと二重にデータが入ってしまいます。

7. さいごに

他にも削除系の操作があれば教えてください。追記させていただきます。

@ruemura3

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む