20200801のRailsに関する記事は20件です。

[Rails]よく作る、基本的な機能まとめ

はじめに

WEBエンジニアとして勉強していて、「Progateドットインストールは終わったけど、これで仕事ができるようになるの?」と疑問に思っている人向けに、個人的によく作る、基本的な機能をまとめてみました。

ここでまとめている機能を一人で作れるようになれば、そのスキルを応用してより発展的な機能を作ることもできるのではないでしょうか。

また、この記事で書いている機能は、単体で完結する1つの機能というよりは、他の機能と連携させて機能するといった場合もあります。

タイトルにRailsと書いてますが、この記事で書いている機能については大体のWEBサービスでよく作るものだと思います。

対象となる方

  • これから仕事でRailsを書いていく予定の人 :muscle:
  • WEBサービスってどんな機能があるのか知りたい人 :thinking:

注意事項

この記事では以下のことは詳しく扱いません。

  • 具体的な実装方法(他に多くの参考情報があるため)
  • Ajax

サンプルコードとして、ブログアプリを想定したコードを書いています

目次

個人的によく作る、基本的な機能を10個あげました。

  • CRUD機能
  • 検索機能
  • パスワード認証機能
  • SNS認証機能
  • メール送信機能
  • ファイルアップロード機能
  • 管理者機能
  • 権限機能
  • 論理削除機能
  • API機能

それぞれの機能の概要と主に連携する機能、そして機能を提供するgemについて説明していきます。

それでは順番にいきましょう!

CRUD機能

概要

CRUD機能は、最も基本となる機能です。CRUDは「クラッド」と呼びます。
以下の4つの機能で構成されています。

  1. 登録機能(Create)
  2. 参照機能(Read)
  3. 変更機能(Update)
  4. 削除機能(Delete)

4つの頭文字をとってCRUDと言われています。

それぞれ簡単に解説します。

  1. 登録機能(Create)

データベースに情報を登録するための機能です。
SQLだとINSERTが実行されます。
基本的には情報を入力するフォームと登録するためのボタンがあり、ボタンを押すことで入力された情報をデータベースに保存するといった形が多いです。

注意点として、特定のページにアクセスしたときにPV数を記録する、といった仕様のときはフォームはないので、データを表示する処理の中でデータベースに保存するといった必要があります。

posts_controller.rb
def create
  @post = Post.new(post_params)
  if @post.save
    redirect_to @post, notice: 'ブログを投稿しました'
  else
    render :new
  end
end
  1. 参照機能(Read)

データベースから情報を取り出すための機能です。
SQLだとSELECTが実行されます。
基本的には情報を表示するページで使います。

注意点として、情報は何度も表示されることが多いので、表示すると同時に他の情報の登録や変更をするようなコードを書いた場合は、データが増えても本当に問題ないか検討したほうがいいと思います。

posts_controller.rb
def index
  @posts = Post.all
end

def show
  @post = Post.find(params[:id])
end
  1. 変更機能(Update)

データベースにある情報を変更するための機能です。
SQLだとUPDATEが実行されます。
データベースに既にある情報に対して、情報を入力するフォームと変更するためのボタンがあり、ボタンを押すことで入力された情報で上書きします。
登録機能(Create)と似たようなコードになることがあります。

posts_controller.rb
def update
  @post = Post.find(params[:id])
  if @post.update(post_params)
    redirect_to @post, notice: 'ブログを更新しました'
  else
    render :edit
  end
end
  1. 削除機能(Delete)

データベースにある情報を削除するための機能です。
SQLだとDELETEが実行されます。
データベースに既にある情報に対して、削除したいときに使います。

注意点として、削除するときに関連する他の情報を消したほうが良いときがあります。
Railsだとdependentオプションを追加することで対応できます。

posts_controller.rb
def destroy
  @post = Post.find(params[:id])
  @post.destroy
  redirect_to posts_url, notice: 'ブログを削除しました'
end
post.rb
has_many :comments, dependent: :destroy
#=> 'dependent: :destroy'を追加すると、postを削除したときに関連するcommentsも全て削除される

主に連携する機能

  • ほとんど全部の機能

gem

  • 特になし
  • RailsのScaffoldコマンドなら自動的にCRUD機能が作られます

検索機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

検索機能はデータベースに保存されている情報の中から、特定の条件に一致するデータを取得するときに使います。
CRUDの参照機能(Read)と合わせて作ることが多いです。
SQLだとWHEREを指定してSELECTが実行されます。

Railsだと一覧画面に検索条件を入力するフォームがあることが多いです。
あと個人的には、検索条件をリセットするボタンをつけたほうが良いと思います。
これは単純に一覧画面へのリンクにして、ボタンの名前を「検索条件をリセット」でいいと思います。

index.html.erb
<%= link_to '検索条件をリセット', posts_path %>

主に連携する機能

gem

パスワード認証機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

パスワード認証機能は、メールアドレスとパスワードの2つを入力してデータベースに保存されているユーザーと一致したらログインさせるといった機能になります。
SQLだとWHEREを指定してSELECTが実行されます。
具体的には、まず入力されたメールアドレスに一致するユーザーを取得して、入力されたパスワードがあっているかを判定します。
パスワードは暗号化してデータベースに保存します。

Railsだとログイン状態にするには、sessionにユーザー情報を保存することが多いです。

sessions_controller.rb
def create
  user = User.find_by(email: params[:user][:email].downcase)
  if user && user.authenticate(params[:user][:password])
    session[:user_id] = user.id
    redirect_to root_url
  else
    render :new
  end
end

主に連携する機能

gem

SNS認証機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

SNS認証機能は、FacebookやGoogle、TwitterなどのSNSに登録されているユーザー情報を取得して、自分で作ったアプリにログインさせるといった機能になります。
各SNSでは、アプリケーションの登録作業が必要です。
例えば、Facebookでは、開発者登録をしてアプリ登録を行うことでSNS認証に必要なアプリIDとSecretIDを取得できます。それらを環境変数で読み込むといったことが多いです。
また、SNSから取得できるユーザー情報は、SNSによって形式が異なることがほとんどです。

Railsでは、omniauthを使うことでそういった異なる形式を一つの統一された形式に変換してくれます。

主に連携する機能

gem

メール送信機能

sozai_cman_jp_20200801150437.png

概要

メール送信機能は、何らかのアクションがあった時にユーザーに通知するためにメールを送信といった機能になります。
例えば、会員登録したユーザーにメールを送ったり、重要な情報をリマインドするためにメールを送ったりします。
メールを送る前にテンプレートを用意しておき、テキスト形式またはHTML形式でメールを送信します。
HTML形式ではCSSを使ってリッチなコンテンツを送信することができますが、CSSはインラインで書いたり、テーブルレイアウトを使ったほうが良い等、いくつかポイントがあります。

Railsでは、メール送信をするためにはSMTPの設定をする必要があり、個人的にはSendgridを使うことが多いです。
開発環境では実際にメールを送信しなくても、本文を確認することができる便利なgemもあります。

主に連携する機能

gem

ファイルアップロード機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

ファイルアップロード機能は、ユーザーが選択した画像ファイル等をアップロードできる機能になります。
例えば、プロフィール画像を変更したり、サムネイル画像を変更したり、またはPDFファイルを添付するといった使い方があります。
基本的にはアップロードしたファイルは、S3などのクラウドストレージに保存するようにして、アプリ内では保持しないようにします。
また、ファイルを選択した時にJavascriptでプレビュー表示をすることも多いです。

Railsでは標準でActiveStorageを使ったシンプルなアップロード機能が提供されています。
より細かいカスタマイズが必要な場合は、carrierwaveなどのgemを使うこともあります。

主に連携する機能

gem

管理者機能

Dashboard___Active_Admin_Depot.png

概要

管理者機能は、CMSなどのように、アプリ内の情報を管理するために管理者を用意する機能です。
ユーザーが見る画面と、管理画面といった形で分けて実装することがあります。
基本的には、管理者アカウントを作成して、各データをCRUDで操作したり、メール送信を行ったりしますが、管理するための多くの機能が含まれていることが多いです。

Railsでは、gemを使ったりnamespaceを使ってユーザーと管理者を分けるといった方法があります。

routes.rb
# 管理者のルーティング(全ての操作ができる)
namespace :admin do
  resources :posts
end

# ユーザーのルーティング(閲覧のみできる)
resources :posts, only: %i[index show]

主に連携する機能

gem

権限機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

権限管理は、ユーザーによって出来ること、出来ないことを管理するための機能です。
例えば、管理者はデータの削除ができるけど、一般は削除できないといった感じです。
また、管理者には削除ボタンを表示するけど、一般には表示しないというように見た目も気にする必要があります。
よくあるのが、ユーザーに管理者フラグのようなカラムを追加して判断するといったものがあります。

Railsでは、自分で実装するかgemを使った方法があります。
個人的には権限が1つくらいなら自前で実装したほうが楽ですが、複数の権限がある場合にはgemを使ったほうがシンプルに実装できると思います。

posts_controller.rb
# 管理者のみ削除できる
def destroy
  return redirect_to root_path unless current_user.is_admin?

  @post = Post.find(params[:id])
  @post.destroy
  redirect_to posts_url, notice: 'ブログを削除しました'
end

主に連携する機能

gem

論理削除機能

無題のスプレッドシート_-_Google_スプレッドシート.png

概要

論理削除機能は、削除機能と違って、データを削除するのではなく、削除フラグなどを使って残しておく機能です。
CRUD機能の削除は物理削除といって、SQLだとDELETEでしたが、論理削除ではUPDATEを実行します。
削除フラグをUPDATEしてONにする感じです。

Railsでは、自分で実装するかgemを使った方法があります。
どちらにも共通して、多いのはdeleted_atのようなカラムを用意して削除した日付を記録するといった方法です。

主に連携する機能

gem

API機能

Json_-_Free_interface_icons.png

概要

API機能は、アプリ内の情報を他のアプリに連携できるようにする機能です。
連携するときのフォーマットはJSONが多いです。
例えば、カレンダーアプリとタスク管理アプリを作ったとして、カレンダーの予定が登録されたらタスク管理アプリに新規でタスクを追加したい、といった時にAPIで情報を連携するといった使い方があります。
他にも、データを管理するAPIサーバーと、データを表示するフロントエンドアプリケーションの2つを連携しながら開発することもあります。

Railsでは標準でAPIモードという機能があり、これを利用することでAPI専用のアプリを作ることができます。
もちろん、通常のRailsアプリを作っていて、あとからAPI機能を追加するといったことも可能です。

posts_controller.rb
def index
  posts = Post.all
  render json: posts
end

主に連携する機能

gem

まとめ

以上、いかがでしょうか?

今回は個人的によく作る、基本的な機能を10個あげました。

  • CRUD機能
  • 検索機能
  • パスワード認証機能
  • SNS認証機能
  • メール送信機能
  • ファイルアップロード機能
  • 管理者機能
  • 権限機能
  • 論理削除機能
  • API機能

特にCRUD機能は必ずといってもいいほど、よく作ります。
実際に、Railsアプリを開発するときも、CRUD機能を中心にして、他の機能を作っていくことが多いです。

これらを一人で実装できれば、ある程度のスキルはあるのではないでしょうか。
また、初めて参加したプロジェクトでコードを読む時にも役に立つと思います。

この記事について、何かありましたらお気軽にコメントください :smiley:

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

mini_magickでmini_magick_processing_errorが出る

画像ファイルを選択して、登録ボタンをおすもエラーが出る。

エラー文には以下の文章が含まれていた。

mini_magick_processing_error

解決方法
ターミナルで以下のコマンドを入力してからサーバーを再起動したら直った。

brew install imageMagick 

参考
http://cojirooo777.blog.fc2.com/blog-entry-37.html

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

scopeでnilを返すとallが適用される

scopeでfindfind_byfirstlastメソッドは使うべきではない

user.rb
scope :normal, -> (type) { where(type: type).first }

このようなscopeでnilを返すと、allが適用されてしまい、User.allが返ってしまう。
これを防ぐためには、scopeでは、ActiveRecord::Relationオブジェクトを返すようにする。
なので、ここでは、firstメソッドを付けずにwhereメソッドで取得する。
whereメソッドでは対象のデータない場合は、nilは返さず、[]を返す。
この[]はActiveRecord::Relationオブジェクト。

user.rb
scope :normal, -> (type) { where(type: type) }

def normal_record(type)
  normal(type).first
end

もしくは、scopeの呼び出し先で、firstメソッドを使うのもあり。
normal(type).first

参考記事

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

[rails]deviseで登録・ログインができない問題

deviseで登録・ログインができない

deviseでユーザー登録とログイン画面を作成した後に、
デフォルト(email)以外の情報で登録・ログインをしたい時用の方法です。

viewページのフォームを編集したのに、登録・ログインできないトラップがありますので、
参考にしてください。

以下の場合、sing_upとaccount_updateのkeyを変更しています。

app/controllers/application.controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
    def configure_permitted_parameters
        if resource_class == User
            devise_parameter_sanitizer.permit(:sign_up, keys: [:name,:email])
            devise_parameter_sanitizer.permit(:sign_in,keys:[:email])
            devise_parameter_sanitizer.permit(:account_update,keys:[:name,:email])
    end
  end
end

defore _action

before_action :configure_permitted_parameters, if: :devise_controller?

before_actionは一種のフィルターのようなもので、application.contollerに記述することで、全てのコントローラーに対して、実行されます。

:devise_contoller?とはdeviseを生成した際にできるヘルパーメソッドの一つで、
deviseに関連する画面に飛ぶなら、ということです。
こうすることで全てのdevise画面でconfigure_permitted_parametersが起動します。

つまりもしそれがdeviseのコントローラーだったら(devise_controller?というメソッドの返り値がtrueだったら)configure_permitted_parametersを呼び出すということです。

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

ec2にdocker環境を構築してみた

railsアプリをec2を利用して本番環境でデプロイした際に、dockerを導入してみました。
ec2にdocker及びdocker-composeをインストールするには以下を参考にしました。
https://qiita.com/y-do/items/e127211b32296d65803a

ec2にsshログインし、mysqlにマイグレーションするまでは以下が詳しく書いてあります。
https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce

MySQLの設定以降

amazon linuxではデフォルトがmariadbのため以下のエラーが出ます。

$ sudo service mysqld start
Redirecting to /bin/systemctl start mysqld.service
Failed to start mysqld.service: Unit not found.

該当する方は以下を参考にmysqlをインストールしてください。
https://qiita.com/hamham/items/fd77bb0bb167a150dc8e#mysql57%E3%81%AE%E5%B0%8E%E5%85%A5

また、ここまで手順どおり進めても以下のコマンドでエラーが出ます。

$ rake db:create RAILS_ENV=production
rake db:migrate RAILS_ENV=production
rake aborted!
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (2)
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

こちらはdockerの導入のためにdatabase.ymlの設定を以下のように変更したためです。

host: localhost #変更前
host: db #変更後

そのため、データベースの作成にはdockerコマンドで実行する必要があります。
しかし、dockerコマンドを実行しようとすると以下のエラーになります。

ERROR: Couldn’t connect to Docker daemon at http+docker://localhost – is it running?

権限不足によるエラーのため、以下を参考に権限を変更してください。
https://qiita.com/dnnnn_yu/items/14a31721a2870b735938

ここまで進んだらdockerコマンドが使用できると思いますので以下のコマンドを実行して下さい。

$ docker-compose up -d コンテナの作成(バックグラウンドで起動モード)
$ docker ps -a 起動しているかの確認

データベースを作成しようとするとエラーが出ます。

$ docker-compose run web rails db:create RAILS_ENV=production
Mysql2::Error::ConnectionError: Access denied for user 'root'@'172.18.0.5' (using password: NO)

これは参考サイトでdatabase.ymlのproduction環境のpasswordが設定されていないからです。
以下のように設定してあげましょう。

// database.yml
production:
  <<: *default
  host: <%= ENV['DB_HOST'] %>
  database: <%= ENV['DB_DATABASE'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>

これでデータベースの作成ができると思います。

$ docker-compose run web rails db:create RAILS_ENV=production
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[rails]deviseで作成したviewページの編集が反映されない

deivseで作成したviewページの編集が反映されない

deviseでデフォルトのログインページを編集し、画面を確認したところ、
編集内容が反映されていない問題が発生したので、解決方法を記録しておきます。

config/initializers/devise.rb
#config.scoped_views = false の記述箇所のコメントアウトを外し、falseをtrueに変更だけ
config.scoped_views = true

これだけで解決しました。

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

minio を同じサーバーの別dockerコンポーネントで立ち上げ、それをnginxプロキシーで外向きの https:// で設置して、fogでそのhttps:// URL をendpoint あるいはasset_hostとして指定すると、IPアドレスになって、サービスを検知できない問題

自分メモです。
正確には、minio を同じサーバーのdockerコンポーネントで立ち上げdocker network経由でも使えるようにした上で、それを同時にnginxプロキシーで外向きの https:// に設定しているので、CarrierWaveのfogでは、その https:// URL をendpointあるいはasset_hostとして指定した場合、Railsで画像アップロードしようとすると、その指定した https:// URL がIPアドレスに変換されてしまい、サービスを検知できない問題……
とにかくこの問題は起こりました。

解決策は、StackOverflow の下記ページにありました。でも、たどり着くのに少し時間がかかった。
asset_hostはそれでいい。しかし、endpointはdockerのコンテナ名を指定すべきと。

StackOverflow: Can't upload file through carrierwave fog-aws to minio (docker-compose)

qiita.rb
CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
      provider:              'AWS',
      aws_access_key_id:     'development',
      aws_secret_access_key: 'development',
      region:                'us-east-1',
      host:                  'minio',  # <- ここをコンテナ名に/サービスのURL(ドメイン名)だとIPアドレスになってしまう
      endpoint:              'http://minio:9000'  # <- ここも
  }
  config.fog_directory  = 'test'
  config.fog_public     = false

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

minio を同じサーバーのdockerコンポーネントで立ち上げている場合に、それをnginxプロキシーで外向きの https:// に設定して、carriawave経由のfogでそのhttps;//ドメインをendpoint あるいはasset_hostとして指定して、Railsで画像アップロードしようとすると、ドメインがIPアドレスになって、サービスを検知できない問題

自分用のメモです。
Rails のstarageを未だ使っていないのがそもそもいけないのだろうか。
とにかくこの問題は起こりました。

解決策は、StackOverflow の下記ページにありました。たどり着くのに少し時間がかかった。

StackOverflow: Can't upload file through carrierwave fog-aws to minio (docker-compose)

qiita.rb
CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
      provider:              'AWS',
      aws_access_key_id:     'development',
      aws_secret_access_key: 'development',
      region:                'us-east-1',
      host:                  'minio', # <- コレ
      endpoint:              'http://minio:9000'# <- コレ
  }
  config.fog_directory  = 'test'
  config.fog_public     = false

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

minio を同じサーバーのdockerコンポーネントで立ち上げている場合に、それをnginxプロキシーで外向きの https:// に設定して、CarrierWave経由のfogでそのhttps://ドメインをendpoint あるいはasset_hostとして指定して、Railsで画像アップロードしようとすると、ドメインがIPアドレスになって、サービスを検知できない問題

自分メモです。
タイトルは実際には
「minio を同じサーバーのdockerコンポーネントで立ち上げdocker network経由でも使えるようにした上で、それを同時にnginxプロキシーで外向きの https:// に設定しているので、CarrierWave経由のfogでは、その https:// URL をendpointあるいはasset_hostとして指定した場合、Railsで画像アップロードしようとすると、その指定した https:// URL がIPアドレスに変換されてしまい、サービスを検知できない問題」とすべきなのですが……
とにかくこの問題は起こりました。

解決策は、StackOverflow の下記ページにありました。でも、たどり着くのに少し時間がかかった。
asset_hostはそれでいい。しかし、endpointはdockerのコンテナ名を指定すべきと。

StackOverflow: Can't upload file through carrierwave fog-aws to minio (docker-compose)

qiita.rb
CarrierWave.configure do |config|
  config.fog_provider = 'fog/aws'
  config.fog_credentials = {
      provider:              'AWS',
      aws_access_key_id:     'development',
      aws_secret_access_key: 'development',
      region:                'us-east-1',
      host:                  'minio',  # <- ここをコンテナ名に/サービスのURL(ドメイン名)だとIPアドレスになってしまう
      endpoint:              'http://minio:9000'  # <- ここも
  }
  config.fog_directory  = 'test'
  config.fog_public     = false

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

Carrierwave導入

Gem file追加

Gemfile
gem 'carrierwave'
gem 'mini_magick'
terminal
$ bundle install

Uploader作成

terminal
$ rails g uploader image
app/models/gear.rb
class Gear < ApplicationRecord
  mount_uploader :image, ImageUploader
end
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include 
~~
  CarrierWave::MiniMagick
~~
  process resize_to_fit: [400, 500]
# それぞれコメントアウトされているので、コメントを外す。

  def default_url
    'board_placeholder.jpg'
  end
# default画像をasset/imageに保存
config/application.rb
module GolfGearReview
  class Application < Rails::Application
    config.autoload_paths += Dir[Rails.root.join('app', 'uploaders')]
  end
end

Carrierwave:
https://github.com/carrierwaveuploader/carrierwave

DBテーブルへ画像保存用のカラムを追加

terminal
$ rails g migration add_image_to_gear image:string
$ rails db:migrate
gears_controller.rb
private
    def gear_params
      params.require(:gear).permit(:name, :description, :club, :maker_id, :club_id, :image)
    end
# :imageの受け渡しを許可

new/edit action時のfile_field追加

app/views/gears/_form.html.erb
<%= simple_form_for @gear do |f| %>
  <%= f.file_field :image %>
<% end %>

画像をindexに表示, link_to設定

app/views/gears/index.html.erb
<% @gears.each do |gear| %>
  <%= link_to (image_tag gear.image.url), gear %>
<% end %>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails / IBM Watson] 使い方メモ

この記事は何?

別のサイトで記録していた内容を移設中です(移設作業進行中...)
元はここに掲載していました。

Text to Speech について

  1. IBMのコンソール画面でインスタンスを作成
    username, password をメモしておく
    参考(IBM)
  2. audioファイル置き場生成
    mkdir public/audios
  3. ソースを書く
app/controllers/hoge_controller.rb
# ↓アクション
def text_to_speech
  json_text = { text: '喋らせたいテキスト' }.to_json
  headers = {
    "Content-Type": 'application/json',
    "Accept": 'audio/wav',              # 作成されるファイル形式を指定。
    "params": { voice: 'ja-JP_EmiVoice' } # 言語の指定。日本人のえみさんに話していただいています。
  }
  response = RestClient.post make_tts_url, json_text, headers

  # Encoding::UndefinedConversionError in StudiesController#request_voice
  # "\xFF" from ASCII-8BIT to UTF-8
  # response.force_encoding('UTF-8') しておくことが必要
  IO.write('public/audios/sample.wav', (response.force_encoding('UTF-8')).body)
end

private

  def make_tts_url
    user_name = '自分のusername'
    pass      = '自分のpassword'
    end_point = 'stream.watsonplatform.net/text-to-speech/api'

    return "https://#{user_name}:#{pass}@#{end_point}/v1/synthesize"
  end
app/views/hoge.html.erb
<%= audio_tag("sample.wav", autoplay: false, controls: true, type: 'audio/wav') %>
<%# public/audios/sample.wavを再生してくれる。 %>
<%# app/assets/audios に同名ファイルがあると、上手くいかないことがある。 %>

感想 (※2018年01月28日当時)

機械音声(Watson)はまだまだぎこちないですね。

「はーい、ワトソン」と喋らせると、「わーい、わとそん」と発音したりします>д<

それから、ローマ字読みなんかを書くと、アルファベット一つずつ読み上げたりもします。

たとえば「hoge」を「ほげ」と呼んでほしいとことですが、「えいちおーじーいー」と読みます;。;

参考URL

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

【チーム開発にて】他メンバーのブランチに移動して、rails sした時のエラー【Rails】

参考対象者

  • チーム開発初心者
  • Railsでのアプリ開発にて、データベース関連のエラーで困ってる方
  • Git初心者

環境

$ rails -v
Rails 6.0.3.1
$ ruby -v
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19]
$ git --version
git version 2.27.0
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using  EditLine wrapper

状況

  • 他メンバーのブランチに移動し、レビューするために挙動確認したかったが、サーバーを立ち上げるときにエラーが出た。
  • どうやら、データベース関連のエラーらしい。

ActiveRecord::PendingMigrationError

https://qiita.com/KONTA2019/items/0444ae3b8c8936a56ee0

上記を参考に、解決する。
ちなみに私は、

$ rails db:migrate

で解決。

でも、その後次のようなエラーが。。。

Multiple migrations have the name ~~~.

結論から言うと、~~~には、マイグレーションファイル名が入ります。

私の場合は、

Multiple migrations have the name CreateUsers.

となって、自分のマイグレーションファイルを確認してみると、

$ rails db:migrate:status

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200618162841  Create tweetposts
   up     20200620004226  Change tweetposts to tweets
  down    20200621075518  Create posts
  down    20200623102444  Change posts to chats
  down    20200627042358  Create users
   up     20200627080839  Create users
   up     20200627083356  Add column to users
  down    20200627220915  Change datatype content of chats
   up     20200703201452  ********** NO FILE **********
  down    20200710035709  Add user id to tweets

ありましたね、CreateUsersファイル。

察しの良い方はお分かりだと思いますが、エラー文の内容から「同名のマイグレーションファイルか存在しているから、どちらを参考にデータベース構築をしたら良いかわからないよ」という状況と推測できます。

なので、
down 20200627042358 Create users
こちらのファイルを削除し、

$ rails db:migrate
$ bundle exec rails s

これにて、サーバーを起動することができました!

ちなみに、、、

マイグレーションファイルの、
up 20200703201452 ********** NO FILE **********

気になりますよね??

これ、ないファイルを参考にデータベースを構築してるという不可思議な現象なので、削除してしまいたいですね。

これの原因は、マイグレーションをdownさせる前に、マイグレーションファイルを削除してしまったため起こるものなのですが、解決方法は下記をどうぞ。

https://qiita.com/beanbeenzou/items/e8886071ab1e1cf7a9c0

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

deviseでのログイン画面実装

deviseでのログイン画面実装

1.Gemfileに「gem 'devise'」を追加

gem 'devise'

2.追加したdeviseを、アプリケーションに読み込ませる。
※gemを追加した時に忘れてはいけない

$ bundle install

3.deviseの初期設定

$ rails g devise:install

これでdeviseを使う準備は完了。

4.Userモデルとマイグレーションファイルを作成
rails g devise モデル名の記述は、devise独自のルールです。

$ rails g devise User

5.データベースへ反映
新しくUserテーブルをデータベースへ反映させます。

$ rails db:migrate

6.deivse用のログイン画面を作成

$ rails g devise:views

7.rails s -b 0.0.0.0でサーバー起動させ、画面確認

image.png

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

現場で学んだRailsリファクタリングの話

現場で学んだ話

Railsの開発で意識している一般的なアーキテクチャの話です。

fatコントローラー、fatモデルにならないように意識していることを備忘録メモ。乱文のため、適宜修正していきます。

コントローラーはシンプルに!!

コントローラーに追わせる責務は、究極的にこう考えています。

「インスタンスを作り、それに対してメソッドを実行して、レスポンスを返す」

これだけ。

こう言うのは最悪。

example.contoroller.rb
こんなアクションとかありえないです

def index
  @most_funded_projects = []
    most_funded_projects = Project.most_funded.includes(:main_image)
    most_funded_projects.each do |most_funded_project|
      break if @most_funded_projects.count >= 3
      if @site_project_descriptions[most_funded_project.id].present?
        @most_funded_projects << most_funded_project
      end
    end
    if @most_funded_projects.count < 4
      current_site.published_projects.order(updated_at: :desc).each do |project|
        break if @most_funded_projects.count >= 3
        @most_funded_projects << project
    end
  end 
end


コントローラーにゴリゴリのビジネスロジックが書かれていますね。こんなコントローラーをかつて書いてたりして、注意されました。scafoldとかでコントローラーを作ると以下のようなシンプルな形のコントローラーができると思いますが、基本的にはこんな感じに沿って作るのが理想です。

example.rb
def index
  @friends = Friend.all

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @friends }
  end
end

要は究極的には、以下のような形が基本

@hoge = Hoge.new
@hoge.hoge
レスポンスを返す

コントローラーが膨らんだ場合は、まずはモデルへ!!

コントローラーでは、そのモデルに紐づくインスタンスを作り、それに対してメソッドを実行するだけのイメージが重要でした。なので、一旦、あらゆるビジネスロジックはモデルに寄せることを考るといいです。
ただ、何でもかんでも寄せるのは別の問題が起きるので、モデルに寄せるのは、主に永続化に関わるものや、単一モデルの操作で完結するビジネスロジックを優先的に寄せるイメージです。

モデルに実装するパターンは以下が一般的。

  • モデルに紐付いたテーブルのレコード取得(ActiveRecordの操作)
  • モデルに紐付いたテーブルをベースとした関連テーブルを含めたデータ取得
  • モデルに紐付いたテーブルのデータ更新
  • その他、単一モデルに紐づくビジネスロジック

単一テーブルの単純な更新など、シンプルな処理が主に該当し、それ以外は単一モデルで完結するビジネスロジックなどかなーと思います。

サービスクラスの活用

複数のモデル操作やファイル操作などの処理を、アトミックなビジネスロジックのひとまとめの単位としてサービス層として切り出します。

基本的には、以下のような形で、ActiveRecordにひもづかない(テーブルと1対1で紐づかない)通常のクラスを作ります。クラスを作り、既存のモデルから複数モデルに跨る複雑なロジックを分離する感じです。使い方は単純で、クラスのインスタンスを作り、それに対して生やしたメソッドを実行するだけです。

exmple.rb
class ExampleService
  def initialize
    ....
  end

  def example
    ....
  end
end

consernやnamespaceを切ってmodelsディレクトリ配下にクラスを作る

紹介した方法でも、モデル、サービスクラスがfatになった場合は、modelsディレクトリ配下に、namespaceを切って、テーブルと1対1になっていない単なるクラスを作り、そこにfatになったモデルやサービスクラス内の汎用的に使えそうなメソッドをこちらに移管させることで、モデル、サービスクラスがfatになるのを防ぐテクニックもあります。また、consernを使って、冗長なものを一つにまとめたりします。例えば、models/{table name}/{use case}.rbを作成して、処理を切り出すイメージです。見通しをよくするためにも、 インスタンス変数の定義はControllerにて行うようにします。

Controller/Service/Modelの分担まとめ

  • ControllerとService層は基本的に手続き処理※のみを行う。※手続き処理とは、関数の呼び出しや、CRUDにまつわる処理を行うこと
  • ControllerとService層は返って来たデータを使うだけでロジックやデータの加工には関知しない
  • Service層は、Controller内の処理が複数Modelにまたがる際に、複数のモデルに生えているメソッドをうまく活用して、サービスクラスにメソッドを作り、主にインスタンスに対して使用する。例えば、複数のモデルに跨る処理などでは、サービスクラス内で、元々、跨る想定の各モデルに生えているインスタンスメソッドを活用し、サービスクラス内でメソッドを生やし、コントローラーでは、サービスクラスのインスタンスを作って、それをレシーバーにしてメソッドを実行するような形をとる。
  • サービスクラスもできる限りfatにしたくないので、ビジネスロジックが嵩ばれば、consernやnamespaceを切ってさらに別のクラスをmodelsディレクトリ配下作るイメージ。models/{table name}/{use case}.rbを作成して、処理を切り出す。見通しをよくするためにも、 インスタンス変数の定義はControllerにて行うようにする。
  • ロジックやデータの加工は必ずModelで行うようにする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Strong Parametersとは?

Strong Parametersとは

Strong ParametersはRails4系から追加されたセキュリティを向上させるための仕組みです。
指定した値以外は受け取らないようにして、攻撃者による意図しないコードの実行を防止するセキュリティ対策。

フォームからデータを送信するときは、「マスアサインメント脆弱性」というセキュリティ上の問題があります。
簡単に伝えると、データ送信時に不正なリクエストによって、予期しない値が変更されてしまう脆弱性です。
Railsでは、この脆弱性を防ぐ「Strong Parameters」の仕組みが用意されています。

こんな感じです。
Strong parametersは必ずprivateより下に記述します。

app/controller/user_controller.rb
class UsersController < ApplicationController
  def create
    user = User.new(user_params)
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end

簡単に言うと、userに関する値(パラメーター)が送信されても「name」「email」しか許可しませんよということです。

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

【Rails】コールバックでターミナルにバリデーションエラーを出力する

◯◯.saveや◯◯.createに失敗する時の原因を教えてくれなくて困る

例えばmessageモデルのインスタンスのsaveに失敗した時

Started POST "/groups/2/messages" for ::1 at 2020-08-01 13:56:59 +0900
Processing by MessagesController#create as */*
  Parameters: {"authenticity_token"=>"PKsrO+YPeqs8AmQ+sB+9YacFtKCb+gpdTkHPTgxG4/vs6wE0swZrWNYXKyBe4ipm9aQDII8PpHSUzL3JPeYPpw==", "message"=>{"content"=>""}, "group_id"=>"2"}
  User Load (25.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 6 ORDER BY `users`.`id` ASC LIMIT 1
  Group Load (0.6ms)  SELECT `groups`.* FROM `groups` WHERE `groups`.`id` = 2 LIMIT 1
  ↳ app/controllers/messages_controller.rb:30:in `set_group'
   (0.2ms)  BEGIN
  ↳ app/controllers/messages_controller.rb:11:in `create'
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 6 LIMIT 1
  ↳ app/controllers/messages_controller.rb:11:in `create'
   (0.2ms)  ROLLBACK

ROLLBACKとだけ出てパッと見では原因がわからない。

【対策1】コントローラでsave!を使う方法

savecreatesave!create!にするとどのバリデーションが原因なのかエラーが表示される。

スクリーンショット 2020-08-01 13.58.42.png

【対策2】モデルでコールバックを使う方法

本題。after_validationを使ってself.errors.messagesなどをputsメソッドで表示する。

<メリット>
・deviseを使ったuserモデルのように、コントローラを触るのが面倒な場合でも使える
・application_record.rbに一度書けばそれぞれのモデルで使える

手順1. pry-railsのgemを導入する

バリデーションエラーが発生した場合にbinding.pryを走らせたいので、いつもどおりpry-railsのgemを導入する。

Gemfile
group :development, :test do
  〜省略〜
  gem 'pry-rails'
end
ターミナル
bundle

手順2. models/application_record.rbにコールバックを追加する

models/application_record.rbに以下を追加する。

application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  ## 以下を追加する

  after_validation :display_validation_result

  private
  def display_validation_result
   ## development以外のときはオフ
    return false unless Rails.env.development?

    puts "============【display_validation_result】============"
    puts "◆◆◆◆◆◆#{self.class.name}モデル◆◆◆◆◆◆"
    puts "+++++属性値一覧++++++"
    self.attributes.each do |key, value|
      puts "#{key}: #{value}"
    end

    ## deviseを使ったuserモデルの場合passwordもputsする
    if self.class.name == "User"
      puts "password: #{self.password}"
    end

    puts "++++++++++++++++++++++++++++"
    ## メインはここから
    puts "★★★★★★バリデーションエラー★★★★★★"
    if self.errors.messages.length == 0
      puts "発生しませんでした"
    else
      puts "バリデーションエラー発生"
      puts self.errors.messages
      binding.pry
    end
    puts "★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"
    puts "==========================="
  end

end

やっていることはバリデーションエラーが発生した時(self.errors.messages.lengthが0出ない時)にself.errors.messagesをターミナルに表示してbinding.pryを走らせているだけ。その他はおまけの情報。

結果

バリデーションエラーが発生してインスタンスのsaveに失敗する時、以下のようにターミナルに出力される。

============【display_validation_result】============
◆◆◆◆◆◆Userモデル◆◆◆◆◆◆
+++++属性一覧++++++
"id: "
"email: dwada"
"encrypted_password: $2a$11$zvwhx8qOe7u62tLbGQCaMOjItYjtjzg5yuaInysQ9wd15SMpMsBti"
"nickname: dadwa"
"first_name: dwadad"
"first_name_reading: dadawdwa"
"last_name: dwada"
"last_name_reading: dadwadwa"
"birthday: 2015-04-10"
"reset_password_token: "
"reset_password_sent_at: "
"remember_created_at: "
"password: dwadad"
++++++++++++++++++++++++++++
★★★★★★バリデーションエラー★★★★★★
バリデーションエラー発生
{:email=>["は不正な値です"], :password_confirmation=>["とパスワードの入力が一致しません"], :first_name_reading=>["はカタカナで入力して下さい。"], :last_name_reading=>["はカタカナで入力して下さい。"], :password=>["は不正な値です"]}

From: /Users/hogehoge/hogehoge/app/models/application_record.rb:27 ApplicationRecord#display_validation_result:

     6: def display_validation_result
     7:   puts "============【display_validation_result】============"
     8:   puts "◆◆◆◆◆◆#{self.class.name}モデル◆◆◆◆◆◆"
     9:   puts "+++++属性一覧++++++"
    10:   self.attributes.each do |key, value|
    11:     p "#{key}: #{value}"
    12:   end
    13: 
    14:   if self.class.name == "User"
    15:     p "password: #{self.password}"
    16:   end
    17: 
    18:   puts "++++++++++++++++++++++++++++"
    19:   puts "★★★★★★バリデーションエラー★★★★★★"
    20:   if self.errors.messages.length == 0
    21:     puts "発生しませんでした"
    22:   else
    23:     puts "バリデーションエラー発生"
    24:     puts self.errors.messages
    25:     binding.pry
    26:   end
 => 27:   puts "★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"
    28:   puts "==========================="
    29: end

[1] pry(#<User>)> 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

セレクターで投稿内容をカテゴライズ

カテゴライズしたいModelを作成

terminal
$ rails g model Club name:string
$ rails db:migrate

今回はGear ModelにClub(Driver, Iron...)属性
を追加するので、Club Model作成

Gear Modelにclub_idを追加

terminal
$ rails g migration add_club_id_to_gears club_id:integer
$ rails db:migrate

Association追加

app/models/gear.rb
class Gear < ApplicationRecord
  belongs_to :club
end
app/models/club.rb
class Club < ApplicationRecord
  has_many :gears
end

gear_controllerのnew actionでclub選択できるよう設定

app/controllers/gears_controller.rb
  def new
    @gear = current_user.gears.build
    @clubs = Club.all.map{ |c| [c.name, c.id] }
  end

  def create
    @gear.club_id = params[:club_id]
  end

  def edit
    @clubs = Club.all.map{ |c| [c.name, c.id]}
  end

  def update
    @gears.club_id = params[:club_id]
  end

  private
    def gear_params
      params.require(:gear).permit(:club_id)
    end

formタグにセレクター追加

app/views/gears/_form.html.erb
<%= simple_form_for @gear do |f| %>
  <%= select_tag(:club_id, options_for_select(@clubs), :prompt => "Select a Club") %>
  <%= f.button :submit %>
<% end %>

editのview編集

app/views/gears/edit.html.erb
<%= simple_form_for @gear, :html => { :multipart => true} do |f| %>
  <%= f.input :name, label: "Gear Name" %>
  <%= f.input :description %>
  <%= f.label :Maker %>
  <%= f.select :maker_id, @makers %>
  <%= f.label :club %>
  <%= f.select :club_id, @clubs %>
  <%= f.button :submit %>
<% end %>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】マイグレーションファイルを削除する

参考対象者

  • マイグレーションファイルの操作の仕方を知りたい方

環境

$ rails -v
Rails 6.0.3.1
$ ruby -v
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19]
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using  EditLine wrapper

マイグレーションファイルを削除する

Add column to usersというファイルを削除したかったとします

  • 削除したいファイルのマイグレーションIDを確認する
$ rails db:migrate:status

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200618162841  Create tweetposts
   up     20200620004226  Change tweetposts to tweets
  down    20200621075518  Create posts
  down    20200623102444  Change posts to chats
  down    20200627042358  Create users
   up     20200627080839  Create users
   up     20200627083356  Add column to users
  down    20200627220915  Change datatype content of chats
  down    20200710035709  Add user id to tweets
  • ID指定して、downさせる
$ rails db:migrate:down VERSION=Add column to users
  • downさせたファイルをゴミ箱へ
$ rm db/migrate/20200703201452_add_column_to_users.rb

downさせる前に、マイグレーションファイルを削除してしまったとき

********** NO FILE **********というファイルで、up状態のファイルを削除したい

  • 削除したいファイルのマイグレーションIDを確認する
$ rails db:migrate:status

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200618162841  Create tweetposts
   up     20200620004226  Change tweetposts to tweets
  down    20200621075518  Create posts
  down    20200623102444  Change posts to chats
  down    20200627042358  Create users
   up     20200627080839  Create users
   up     20200627083356  Add column to users
  down    20200627220915  Change datatype content of chats
   up     20200703201452  ********** NO FILE **********
  down    20200710035709  Add user id to tweets
  • 削除したマイグレーションファイル名と同名のファイルを作成する
$ touch db/migrate/20200703201452_add_column_to_users.rb
20200703201452_add_column_to_users.rb
class AddColumnToUsers < ActiveRecord::Migration
  def change
  end
end
  • downさせて、作成したマイグレーションファイルを削除する
$ rails db:migrate:down VERSION=20200703201452
$ rm db/migrate/20200703201452_add_column_to_users.rb
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

resourcesでルーティングを設定する方法

resourcesでルーティングを設定する

ルーティングは、個別に設定も可能です。
ただし、railsでの基本的な7つのアクションは開発の際によく使われるので、
そのたびに設定するのは効率的とはいえません。
こんなときは、resourcesメソッドを利用すると、ルーティングを1行書くだけで自動設定されます。

Rails.application.routes.draw do
  resources :blogs
end

rails routesコマンドで確認。

$ rails routes

全てのurlが設定されていることを確認。

$ rails routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    blogs GET    /blogs(.:format)                                                                         blogs#index
                          POST   /blogs(.:format)                                                                         blogs#create
                 new_blog GET    /blogs/new(.:format)                                                                     blogs#new
                edit_blog GET    /blogs/:id/edit(.:format)                                                                blogs#edit
                     blog GET    /blogs/:id(.:format)                                                                     blogs#show
                          PATCH  /blogs/:id(.:format)                                                                     blogs#update
                          PUT    /blogs/:id(.:format)                                                                     blogs#update
                          DELETE /blogs/:id(.:format)                                                                     blogs#destroy
       rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

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

Railsのバリデーションの種類と使い方

プログラミングの勉強日記

2020年8月1日 Progate Lv.226

バリデーションとは

 不正なデータがデータベースに保存されないようにデータをチェックするシステムをバリデーションという。バリデーションに引っかかった場合(不正なデータの場合)にはデータベースに保存されない。

基本的な書き方

 モデルクラスにvalidatesメソッドを指定することで、バリデーションをかけることができる。(バリデーションはモデルで設定する。)このときに、validatesを用いてカルム名と内容を指定する。

model/ファイル名.rb
validates :カラム名(シンボルで指定),検証ルール(こちらもシンボルで指定)

バリデーションの種類

空ではい(空のデータを登録できないようにする)

 {presence: true}を用いることでそのカラムの値が存在するかどうかをチェックできる。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true}
end

boolean属性が空でないこと

models/users.rb
class User < ApplicationRecord
  validates :birthplace, inclusion: { in: [true, false] }
end

チェックボックス

models/users.rb
class User < ApplicationRecord
  validates :gender, {acceptance: true}
end

文字数の指定

 lengthを用いて{maximum:数値}を指定することで最大文字数を{minimum:数値}で最小文字列を指定することができる。またinを使うことで範囲やその文字数のみのバリデーションをかけることもできる。

models/posts.rb
class Post < ApplicationRecord
  # 最大140文字(140文字以下)
  validates :content, {length : {maximum:140} }

  # 50文字以上
  validates :content, {length : {minimum:50} }

  # 1文字以上75文字以下
  validates :content, {length: {in: 1..75} }

  # 5文字のみ
  validates :content, {length: {is: 5} }
end

数値の指定

 数値のみの入力を許可するときには、numericalityを使う。

models/actorrb
class Actor < ApplicationRecord
    validates :height, {numericality: true}
end

 numericalityは様々なオプションがあるので、これらを用いることでより詳細なバリデーションをかけることができる。

オプション 概要
only_integer integerのみ
equal_to 指定された値と等しいか
greater_than_or_equal_to 指定された値以上
less_than_or_equal_to 指定された値以下
greater_than 指定された値よりも大きいか
less_than 指定された値よりも小さいか
odd trueに設定した場合、奇数か
even trueに設定した場合、偶数か
models/actor.rb
class Actor < ApplicationRecord
  # 50より大きく250より小さい
  validates :height, numericality: {greater_than: 50,less_than: 250}
end

任意で指定した値が含まれているかどうか

指定した値が含まれているか確認するときはinclusionを使う。

models/actor.rb
class Actor < ApplicationRecord
 validates :blood_type, inclusion: {in: ['A','B','O','AB']}
end

 指定した値が含まれていないか確認するときはexclusionを使う。

models/actor.rb
class Actor < ApplicationRecord
 validates :gender, exclusion: {in: ['male','female']}
end

値の重複

 値の重複がないかをチェックするための{uniqueness: true}というバリデーションもある。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {uniqueness: true}
end

 

おまけ

複数のバリデーションの指定

 バリデーションの内容はハッシュになっているので、コンマで区切ることで複数指定できる。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true, length : {maximum:140}}
end

自分で決めたエラーメッセージを表示する

 messageを追加することで自分で指定したエラーメッセージを表示させることもできる。

models/actor.rb
class Actor < ApplicationRecord
  validates :height, numericality: {greater_than: 50,less_than: 250, message: " : Please input 50~250"}
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む