- 投稿日:2020-04-04T23:32:05+09:00
[*Rails*] deviseの使い方(rails6版)
はじめに
Rails6での再再検証版です。
以下のRails5のときのものをRails6で実行し、一部変更になっている部分を反映したバージョンです。
[Rails] deviseの使い方(rails5版)【前回】 rails : 5.0.0.1 ruby : 2.3.1 devise: 4.2.0 ↓ 【今回】 rails : 6.0.2.2 ruby : 2.7.1 devise: 4.7.1deviseとは
ユーザー登録して、送られてきたメールのリンクをクリックして本登録して、ログインして、パスワード忘れたら再設定して、何回もログインミスったらアカウントロックして…などといった認証系アプリに必要な機能を簡単に追加できる便利なgemです。
1. gemのインストール
1. プロジェクトの作成
新しいプロジェクトを作ります。
$ rails new devise_rails6 $ cd devise_rails6/2. Gemfileの編集とインストール
以下ファイルに
devise
とomniauth-twitter
を追加します。source 'https://rubygems.org' # (省略)... # Devise gem 'devise' gem 'omniauth-twitter'gemをインストール。
$ bundle install2. deviseの設定
devise関連ファイルを追加。
すると以下のような英文が表示されます。1から4まで順番に見ていきます。$ rails generate devise:install Running via Spring preloader in process 30440 create config/initializers/devise.rb create config/locales/devise.en.yml =============================================================================== Some setup you must do manually if you haven't yet: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> 4. You can copy Devise views (for customization) to your app by running: rails g devise:views ===============================================================================1. デフォルトURLの指定
英文の例に書いてあった
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
を以下のファイルに追加しました。
config.action_mailer.default_url_options = { host: 'localhost:3000' }
でもOKです。config/environments/development.rbRails.application.configure do # Settings specified here will take precedence over those in config/application.rb. # (省略)... # mailer setting config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # config.action_mailer.default_url_options = { host: 'localhost:3000' } end2. root_urlの指定
1番で指定した
http://localhost:3000/
にアクセスした際に表示されるページを指定します。
現状ページは1つも作っていないため、先に追加します。Pagesコントローラーと、indexページとshowページを追加してみます。
$ rails g controller Pages index show
routes.rb
に以下を指定します。config/routes.rbRails.application.routes.draw do root 'pages#index' get 'pages/show' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end3. flashメッセージの設定
ログインした時などに上の方に「ログインしました」みたいなメッセージが出るようにします。
以下のファイルの<body>
タグのすぐ下に指定されたタグを挿入します。app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title>DeviseRails6</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <!-- ここに追加 --> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html>4. deviseのViewを生成
deviseの導入で追加されるViewは、以下のコマンドを実行しなければデザインを変更できないので、デザインをカスタマイズするためにも実行します。
$ rails g devise:views
すると以下の様なファイルが生成されます。
app/views/devise/shared/_error_messages.html.erb (エラーメッセージ用パーシャル) app/views/devise/shared/_links.html.erb (リンク用パーシャル) app/views/devise/confirmations/new.html.erb (認証メールの再送信画面) app/views/devise/passwords/edit.html.erb (パスワード変更画面) app/views/devise/passwords/new.html.erb (パスワードを忘れた際、メールを送る画面) app/views/devise/registrations/edit.html.erb (ユーザー情報変更画面) app/views/devise/registrations/new.html.erb (ユーザー登録画面) app/views/devise/sessions/new.html.erb (ログイン画面) app/views/devise/unlocks/new.html.erb (ロック解除メール再送信画面) app/views/devise/mailer/confirmation_instructions.html.erb (メール用アカウント認証文) app/views/devise/mailer/email_changed.html.erb (メール用メールアドレス変更完了文) app/views/devise/mailer/password_change.html.erb (メール用パスワード変更完了文) app/views/devise/mailer/reset_password_instructions.html.erb (メール用パスワードリセット文) app/views/devise/mailer/unlock_instructions.html.erb (メール用ロック解除文)3. Userモデルの設定
1. Userモデルの作成
以下を実行。
$ rails g devise User
マイグレーションファイルができます。
デフォルトではこんな感じになってます。db/migrate/20200404040003_devise_create_users.rb# frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable # t.integer :sign_in_count, default: 0, null: false # t.datetime :current_sign_in_at # t.datetime :last_sign_in_at # t.string :current_sign_in_ip # t.string :last_sign_in_ip ## Confirmable # t.string :confirmation_token # t.datetime :confirmed_at # t.datetime :confirmation_sent_at # t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true # add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end endUserモデルはこんな感じになっています。
デフォルトではdatabase_authenticatable
、registerable
、recoverable
、rememberable
、validatable
が使えるようになっています。app/models/user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end2. deviseモジュール概要
各モジュールについて以下に紹介します。
機能 概要 database_authenticatable サインイン時にユーザーの正当性を検証するためにパスワードをハッシュ化してDBに登録します。認証方法としてはPOSTリクエストかHTTP Basic認証が使えます。 registerable 登録処理を通してユーザーをサインアップします。また、ユーザーに自身のアカウントを編集したり削除できるようにします。 recoverable パスワードをリセットし、それを通知します。 rememberable 保存されたcookieから、ユーザーを記憶するためのトークンを生成・削除します。 trackable サインイン回数や、サインイン時間、IPアドレスを記録します。 validatable Emailやパスワードのバリデーションを提供します。独自に定義したバリデーションを追加することもできます。 confirmable メールに記載されているURLをクリックして本登録を完了する、といったよくある登録方式を提供します。また、サインイン中にアカウントが認証済みかどうかを検証します。 lockable 一定回数サインインを失敗するとアカウントをロックします。ロック解除にはメールによる解除か、一定時間経つと解除するといった方法があります。 timeoutable 一定時間活動していないアカウントのセッションを破棄します。 omniauthable intridea/omniauthをサポートします。TwitterやFacebookなどの認証を追加したい場合はこれを使用します。 3. Userモデルの編集
今回はデフォルトではないものも触ってみたいと思うので全部入れてみます。
Twitter認証を使うのでTwitterを指定しています。app/models/user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :lockable, :timeoutable, :trackable, :omniauthable, omniauth_providers:[:twitter] end4. マイグレーションファイルの編集
上に合わせて使用モジュールに対応する部分のコメントアウトを外します。今回は全部使うので全部外します。
全部を使用しない場合は 3. で使うことにしたものに関連する項目だけコメントアウトを外してください。db/migrate/20200404040003_devise_create_users.rb# frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, default: 0, null: false t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip t.string :last_sign_in_ip ## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # Only if using reconfirmable ## Lockable t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts t.string :unlock_token # Only if unlock strategy is :email or :both t.datetime :locked_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true add_index :users, :confirmation_token, unique: true add_index :users, :unlock_token, unique: true end end5. omniauth-twitter用カラムの追加
ついでに
omniauth-twitter
で使うprovider
とuid
、それとTwitter認証の場合はアカウント名を保存しておきたいのでusername
もUserテーブルに追加します。
その他、保存したい項目があったら arunagw / omniauth-twitter の認証時のハッシュ情報を参考に保存用カラムを追加してください。$ rails g migration add_columns_to_users provider uid username
以下のようなマイグレーションファイルができます。
db/migrate/20200404042756_add_columns_to_users.rbclass AddColumnsToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :provider, :string add_column :users, :uid, :string add_column :users, :username, :string end endここまで出来たら以下を実行します。
$ rake db:migrate
4. viewの編集
以下のファイルを編集して、ページ上部にメニューが出るようにします。
user_signed_in?
はdeviseのHelperメソッドです。
ログインしているかしてないかで上部のメニューの表示が変わるようになります。
current_user
で現在サインインしているユーザーの情報を取得できます。app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title>DeviseRails6</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <header> <nav> <% if user_signed_in? %> <strong><%= link_to current_user.username, pages_show_path %></strong> <%= link_to 'プロフィール変更', edit_user_registration_path %> <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %> <% else %> <%= link_to 'サインアップ', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %> <% end %> </nav> </header> <!-- ここに追加 --> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> <%= yield %> </body> </html>以下の2ページも修正。
indexの方がトップページ、showの方がログインしているユーザー用のページになる予定です。app/views/pages/index.html.erb<h1>ようこそ</h1> <p>トップページです。</p>app/views/pages/show.html.erb<h1>こんにちは、<%= current_user.username %>さん</h1> <p>ユーザー用ページです。</p>サーバーを立ち上げて、「サインアップ」を押下すると、
app/models/user.rb
でomniauthable
を設定しているのに何の設定もしていないので現状ではエラーになります。$ brew install yarn $ rails webpacker:install $ rails s
omniauthable
を設定していない場合はサインアップページが表示されます。Twitterで認証する
1. 設定
1. Twitter Developerの登録
Twitter Developerにアクセスし、
Create an app
をクリックし(ツイッターにログインしてないとボタンが出ません)、情報を入力にします。
審査がいるようになってしまったので、私がやったときは何週間かかかった気がします。
私は今回、rails5版のこの記事を書いたときのものを使用しています。新規申請する場合は、申請時に
Enable Sign in with Twitter
にチェックを入れておいてください。2. 設定ファイルの編集
Keys and tokens
タブを開き、API key
とAPI secret key
を以下の該当箇所にコピーして貼り付けます。
callback_url
をhttp://127.0.0.1:3000/users/auth/twitter/callback
にし、Twitter Developer側のコールバックの設定も変更する必要があるようです。
なので、以下の用に修正しました。config/initializers/devise.rbDevise.setup do |config| # (省略)... config.omniauth :twitter, 'API Key', 'API Secret', callback_url: 'http://127.0.0.1:3000/users/auth/twitter/callback' end2. 動作確認
サーバーを立ち上げてサインアップページの下の方にあるSign in with Twitterというリンクをクリックします。
すると以下の様な画面が開くのでログインして
連携アプリを認証
をクリックします。こんな画面が出るはずです。
3. コールバック用コントローラーの作成
Twitter認証後適切に画面が遷移するように以下を実行してコントローラーを作ります。
$ rails g controller omniauth_callbacks
作成したコントローラーの中身を以下のように修正します。
継承するのがDevise::OmniauthCallbacksController
になっていることに注意です。
omniauth.auth
という環境変数に認証に関する情報が入っています。
その情報を使ってユーザーが登録されているかを検証し、登録してる場合はログイン、登録されてない場合は登録用ページに遷移します。app/controllers/omniauth_callbacks_controller.rbclass OmniauthCallbacksController < Devise::OmniauthCallbacksController def twitter @user = User.from_omniauth(request.env["omniauth.auth"].except("extra")) if @user.persisted? sign_in_and_redirect @user else session["devise.user_attributes"] = @user.attributes redirect_to new_user_registration_url end end endちなみに
omniauth.auth
の中にはこんなものが入ってます。(一部の値は適当に変えてあります。){ "provider"=>"twitter", "uid"=>"0123456789", "info"=>{ "nickname"=>"manycicadas", "name"=>"芭蕉", "location"=>"関東", "image"=>"http://pbs.twimg.com/profile_images/483964583371997185/2ZqzhzKV_normal.png", "description"=>"JavaEE/Ruby(Rails)/HTML/CSS/JavaScript/Raspberry Pi などなどが好き。", "urls"=>{ "Website"=>nil, "Twitter"=>"https://twitter.com/manycicadas" } }, "credentials"=>{ "token"=>"xxx", "secret"=>"xxxxxx" } (省略)... }Userモデルに
self.from_omniauth
とself.new_with_session
を作ります。
self.from_omniauth
ではuid
とprovider
で検索してあったらそれを、無かったらレコードを作ります。
self.new_with_session
については、もしこのメソッドを追加しておかなければ、Twitter認証後サインアップページで登録を行っても、認証情報として取ってきたuidやproviderなどが登録されません。それらが登録されないのでTwitterで認証しても登録されてないユーザーとして毎回サインアップページに飛ばされます。app/models/user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :lockable, :timeoutable, :trackable, :omniauthable, omniauth_providers:[:twitter] def self.from_omniauth(auth) find_or_create_by(provider: auth["provider"], uid: auth["uid"]) do |user| user.provider = auth["provider"] user.uid = auth["uid"] user.username = auth["info"]["nickname"] end end def self.new_with_session(params, session) if session["devise.user_attributes"] new(session["devise.user_attributes"]) do |user| user.attributes = params end else super end end end以下ファイルを編集して、コールバック用のコントローラーとしてさっき作ったコントローラーが呼ばれるようにします。これを書かないとdevise側のコントローラーが呼ばれます。
config/routes.rbRails.application.routes.draw do devise_for :users, controllers: { :omniauth_callbacks => "omniauth_callbacks" } root 'pages#index' get 'pages/show' # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html endこれでTwitter認証ができるようになりました。
初回、Twitter認証を行うと、サインアップページに飛ばされ、そこでメールアドレスやパスワードを入力して登録するとユーザー情報が登録されます。
今回はcomfirmable
機能を入れているので、登録したら確認メッセージを送ったとのメッセージが出て、そのままログインすることはできません。
この機能を入れてなかった場合、登録すると即ログインします。アカウント登録確認メールを送る
1. comfirmable概要
多くの登録系サイトで採用されている、登録すると仮登録状態になり、届いたメールのリンクをクリックするとログイン可能になるという仕組みを追加できるのがcomfirmableです。
今回はGmailのアカウントを使って実際にメールが届くように設定します。2. ログを見る
log/deployments.logDevise::Mailer#confirmation_instructions: processed outbound mail in 8.8ms Delivered mail 5e881d3772753_89a53b9c70510@SampleMacBook-Pro.local.mail (22.3ms) Date: Sat, 04 Apr 2020 14:37:59 +0900 From: please-change-me-at-config-initializers-devise@example.com Reply-To: please-change-me-at-config-initializers-devise@example.com To: sample@example.com Message-ID: <5e881d3772753_89a53b9c70510@SampleMacBook-Pro.local.mail> Subject: Confirmation instructions Mime-Version: 1.0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit <p>Welcome sample@example.com!</p> <p>You can confirm your account email through the link below:</p> <p><a href="http://localhost:3000/users/confirmation?confirmation_token=1vus7S8UesPoay5yz2je">Confirm my account</a></p>3. メールが実際に届くようにする
1. 設定ファイルの編集
今回はgmailを使うのでメールアドレスにはgmailを設定します。
デフォルトの設定があると思うので、それを変更してください。config/initializers/devise.rbDevise.setup do |config| # (省略)... config.mailer_sender = "メールアドレス" endgmailの場合はGメールアドレスとGメールパスワードの部分を自分のアカウントのものに変更します。
config/environments/development.rbRails.application.configure do # (省略)... # mailer setting config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # config.action_mailer.default_url_options = { host: 'localhost:3000' } config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { :address => 'smtp.gmail.com', :port => 587, :user_name => 'Gメールアドレス', :password => 'Gメールパスワード', :authentication => :plain, :enable_starttls_auto => true } end2. Gmailの設定
1. とりあえず試したい場合
デフォルトでは安全性の低いアプリケーションからGmailへのアクセスが制限されています。
よってその制限を解除することで動くようにできます。
ただ、安全性の低いアプリからのアクセスを許可するということはセキュリティ的にはいまいちなのであくまで動作確認ように利用することをおすすめします。
安全性の低いアプリがアカウントにアクセスするのを許可する の安全性の低いアプリを許可というリンクをクリックして、以下のように設定します。2. 2段階認証がオンの場合
2段階認証をオンにしている場合、1の設定はできないはずなのでこちらをやってください。
また、1のセキュリティ的にイマイチな方をやりたくない方もこの際2段階認証をオンにしてこの設定をやってください。アカウントへのアクセスとセキュリティ設定の管理を開きます。
2段階認証がオフの場合は2段階認証プロセスから2段階認証の設定をしてください。(2 段階認証プロセスを有効にする)
2段階認証設定を行っている場合はアプリパスワードを開きます。
アプリを選択
でその他
を選択します。適当に名前をつけます。
パスワードが生成されます。
生成されたパスワードを、1の設定の
:password => "Gメールパスワード",
のGメールのパスワードの部分に設定します。3. 届いたメールを確認
これでアプリ側からサインアップすると、以下の様なメールが届くようになります。
Confirm my account
をクリックするログイン画面からログインが可能になります。メールで送られる文章は以下のファイルを編集することで可能です。
app/views/devise/confirmation_instructions.html.erb
アカウントをロックする
1. lockable概要
アカウントの認証を一定回数間違うと、アカウントをロックするようにする機能です。
2. 設定
1. 設定ファイルの編集
以下ファイルを修正して、アカウントの認証を5回失敗します。
config/initializers/devise.rbDevise.setup do |config| # (省略)... # lock sessings config.unlock_strategy = :email config.maximum_attempts = 4 endするとアカウントがロックされてこのようなメールが届きます。
メールの中身は
app/views/devise/mailer/unlock_instructions.rb
ファイルを修正すれば変わります。2. 設定値について
- lock_strategy(ロック方法)
属性 説明 :failed_attempts 失敗回数によってロック。 :none ロックしない。
- unlock_strategy(ロック解除方法)
属性 説明 :time 指定時間でロックを解除する。 メールでロックを解除する。 :both :timeと:emailの両方。 :none 解除させない。
:none
を指定した場合、ユーザーのレコードのlocked_at
カラムをnil
にアップデートしたらロックが解除できます。
- unlock_in(ロック解除時間)
2時間で解除するなら
config.unlock_in = 2.hours
といった具合に指定。
- unlock_keys
アカウントをロックまたは解除するときに使用するキーを定義するらしいです。
config.unlock_keys = [:username]
という感じで指定できます。
- maximum_attempts(失敗可能回数)
アカウントの認証を失敗して良い回数を指定します。
config.maximum_attempts = 4
と指定した場合、4回目までは失敗しても大丈夫ですが、5回目を失敗した時点でアカウントがロックされます。セッションをタイムアウトする
1. timeoutable概要
一定時間活動がない場合にセッションをタイムアウトさせるのがtimeoutableです。
2. 設定
以下ファイルを修正するとタイムアウトまでの時間を指定できます。
以下の場合だと3分後にセッションがタイムアウトします。
デフォルトは30分だそうです。config/initializers/devise.rbDevise.setup do |config| (省略)... # timeout setting config.timeout_in = 3.minutes endその他の設定
1. ログイン後のページを変更する
ログインすると、デフォルトでは
root_url
に飛ばされます。
これをapp/views/pages/show.html.erb
になるように修正します。
after_sign_in_path_for
メソッドを追加します。ここにログイン後に遷移したいページを指定します。
あとsign_in_required
も追加します。showページはログインしているユーザーだけにアクセスさせ、ログインしてない場合はログインページに遷移させます。app/controllers/application_controller.rbclass ApplicationController < ActionController::Base def after_sign_in_path_for(resource) pages_show_path end private def sign_in_required redirect_to new_user_session_url unless user_signed_in? end endPagesコントローラーに
before_action
を追加します。app/controllers/pages_controller.rbclass PagesController < ApplicationController before_action :sign_in_required, only: [:show] def index end def show end endこれでログイン後showページに遷移するようになります。
2. サインアップする際に登録するパラメーターを増やす
ユーザーを登録するときにデフォルトではEmailとパスワードだけですが、
ユーザー名も登録させたい、などの場合があると思います。まずはサインアップページにユーザー名を入力するエリアを追加します。
ユーザーのプロフィール変更ページ(views/devise/registrations/edit.html.erb
)にも同様に追加しときます。app/views/devise/registrations/new.html.erb<h2>Sign up</h2> <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> # (省略)... <!-- ユーザー名を追加 --> <div class="field"> <%= f.label :username %><br /> <%= f.text_field :username %> </div> # (省略)... <%= render "devise/shared/links" %>次に
ApplicationController
に以下を追加します。
テンプレートを変えて、ユーザー名を入力するようにしただけでは実際に登録されないからです。
詳しくはstrong_parameters
について調べてください。
簡単に言えばよく分からんパラメーターは渡せないようになってるので渡せるようにします。app/controllers/application_controller.rbclass ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :configure_permitted_parameters, if: :devise_controller? # (省略)... protected def configure_permitted_parameters devise_parameer_sanitizer.permit(:sign_up, keys: [:username]) devise_parameter_sanitizer.permit(:account_update, keys: [:username]) end end最後に
作ったプロジェクト全体は以下です。
cigalecigales/devise_rails6
- 投稿日:2020-04-04T23:06:46+09:00
bundle install --deploymentでAWS Lambda向けデプロイパッケージを作っていて嵌った罠
背景
AWS lambdaにRubyスクリプトを配置するデプロイパッケージを作るとき、Rubyスクリプトが依存するgemファイルをzipファイルに含めるため、
bundle install --deployment
のように、--deployment
オプションを指定していました。
--deployment
オプションを指定するとgemはvendor/bundle
ディレクトリにインストールされます。
次のコマンドで、vendor
ディレクトリをデプロイパッケージに含めます。zip deploy_package lambda_function.rb -FSr vendor
--deployment
オプションを使っているのは、AWSのデプロイスクリプトのサンプルにbundle install --deployment
が使われていた時があり、その名残です。現在ではbundle install --path vendor/bundle
が使われています。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/ruby-package.html
bundle install --path vendor/bundle
を使っていれば、この先を読む必要はありません。物語
PCにインストールしているbundlerのバージョンを2.1.4に上げました。
bundler 2.1.4では
--deployment
オプションは非推奨になりました。
代わりにbundle config deployment true
コマンドで設定を変更します。
https://github.com/rubygems/bundler/pull/7519CI環境で使うデプロイスクリプトも
bundle config deployment true
に修正しました。デプロイが失敗するようになりました。
gemがvender/bundle
ディレクトリにインストールされなくなったようです。原因
CI環境ではRuby 2.7を使っています。
Ruby 2.7に同梱されているbundlerのバージョンは2.1.2でした。bundler 2.1.2 では
bundle config deployment true
を設定しても、gemのインストール先が変わりません。対策
bundle config set path 'vendor/bundle'
を設定して、gemのインストール先をvender/bundle
にしました。これでbundler 2.1.2でも2.1.4でもgemは
vendor/bundle
ディレクトリにインストールされます。その後
CI環境でbundler 2.1.4を使うようになり、1ヶ月半くらいで
bundle config deployment true
に戻しました。
--path
オプションも非推奨なので、bundle install --path vendor/bundle
にはしませんでした。
- 投稿日:2020-04-04T23:02:55+09:00
MVCとは
MVC
Model(モデル)
View(ビュー)
Controller(コントローラー)
の頭文字です。
役割としては
Model(モデル)
ビジネスロジック(データ処理)を行う
View(ビュー)
表示処理を行う
Controller(コントローラー)
リクエストに応じて適切な処理を呼び出すMVCの流れ
ルーティング=>コントローラー
リクエストに対応したルーティングが読まれ、それに対応したコントローラーのアクションが動きます。
コントローラー=>モデル
コントローラーで呼び出したアクションをモデルを通してデータベースから必要なデータを呼び出します。
コントローラー=>ビュー
呼び出したデータをビューに受け渡し、受け取ったデータをWebページに表示させます。
- 投稿日:2020-04-04T22:42:29+09:00
[Rails]本番環境でSeed-fuを使う
本記事投稿のいきさつ
railsでアプリを作成している中で、Seed_fu Gem を使用しました。
その際、開発環境では上手くテーブルにデータを格納することができたのですが、本番環境で苦戦したため備忘録として書きます。
ここでは、自分が苦戦したEC2内でのコマンドのみを書きます。エラー(異なるディレクトリでコマンドを入力していたため)
自分が作成したアプリのディレクトリへ移動しコマンドを入力したところ
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)と、mysplに接続ができないというエラーが発生。
これはコマンドを入力するディレクトリが誤っていたため発生したエラーでした。
実は開発環境とは異なり、本番環境ではcurrentディレクトリ内のデータが本番環境で動いているフォルダ群になります。
そのためcurrentディレクトリへ移動した後、再度コマンドを入力します。cd current rails db:seed_fuこれで大丈夫かと思われましたが、またしてもエラーが。
エラー(コマンド誤り)
Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfilelisten gem がないとのこと。
まさかと思いgemfileを確認したところちゃんと書かれていました。
調べたところ、seedでデータを投入する際は環境の指定をする必要があるようです。ということで以下を再度実行。rails db:seed_fu RAILS_ENV=production今度は成功しました。初めての経験で苦戦しましたが、とても勉強になりました。
ちなみに、test環境でも同じように以下を実行すれば大丈夫です。rails db:seed_fu RAILS_ENV=testおわり
最後まで見ていただきありがとうございました。
- 投稿日:2020-04-04T22:36:41+09:00
for文の基本
環境,前提
Ruby 2.5.1
MacOS Mojave Ver.10.14.6本記事はRubyがインストールされた前提の記事です。
Rubyをインストールしたあと、とにかくRubyをいろいろ触ってみて慣れていくための記事です。お役に立てば幸いです。for文の基本
オブジェクトの中身から1つずつ取り出して、変数に代入して、オブジェクトの中身を全て処理するまでループが回り続けます。
sample.rbfor 変数 in オブジェクト do //繰り返したい処理 endでは1から10までの合計をfor文を用いて算出してみます。
sample.rbsum = 0 for i in 1..10 do sum += i end puts sum実行結果は以下のように55となります。
Tarminal55範囲オブジェクト
ここで1..10ってなんだろう?と思われた方も多いはずです。これは範囲オブジェクトといい、
ここで登場する1..10というのは範囲オブジェクトといいRuby独特の物です。開始値と終了値を..で結べば範囲オブジェクトとなります。Rubyでは範囲ですらオブジェクトです。解説
先ほどのfor文において
sample.rbfor i in 1..10 doの記述の部分は
1から10までの整数を順番に取り出してiに代入して
sum += i を実行するということです。補足
範囲オブジェクトの開始と終了は具体的な数値である必要はなく、変数でも構いません。よって以下のように書くこともできます。
sample.rbform = 1 to = 10 sum = 0 for i in form..to do sum += i end puts sum実行結果は以下のように55となります。
Tarminal55
- 投稿日:2020-04-04T22:08:31+09:00
selfを使って、undefined methodエラーを解消
はじめに
Modelで定義したメソッドがControllerで呼び出せなくなったとき、
selfを使って2パターンの解決法を見つけたため、記録として残しておく。今回は、helloという名前のメソッドをモデルで定義するという設定とする。
解決法1(特異メソッド方式)
post.rbclass Post def self.hello puts 'hello' end endメソッド名の前にself.をつけるやり方
ruby初学者なら何度も見たことのある形だ。
解決法2(特異クラス方式)
post.rbclass Post class << self def hello puts 'hello' end end endこちらでも、きちんとcontrollerで呼び出すことができた。
この場合だと、メソッド名の前にself.を書く必要もないし、class << self と end内であれば、
複数のメソッドを同じように定義できるのがメリットだ。post.rbclass Post class << self def hello puts 'hello' end def goodmorning # 二つ定義しても self つけなくて良い puts 'Good morning' end end endそもそも
ここからは、特異メソッド方式や特異クラス方式、selfについてもう一歩踏み込んだところまで理解したい方々に読んで欲しい。
class << selfの仕組み
特異メソッド
hello = 'hello' def hello.say puts hello + 'world' end hello.say #=> hello world another_hello = 'hello' another_hello.say #=> NoMethodError: undefined method `say' for "hello":Stringこのように、特異メソッド(hello.say)とは、オブジェクト(hello)に直接固有のメソッドを定義したものだ。
なので、上記のように別のオブジェクト(another_hello)には使うことはできない。これに加えて、もう一つ特異メソッドを定義する方法がある。
hello = 'hello' class << hello def say_world puts "#{self}, world" end end hello.say_world #=> hello, worldこれも << hello というところで helloオブジェクトの特異クラスを引き出しており、あくまでオブジェクトに対しての特異メソッドの定義となっている。
つまり、一番最初のこの部分、
class Post class << selfクラス定義のコンテキストでの self とは、Classクラスのインスタンス Post class だ。class Post とはクラスを定義するときの記法だが、Ruby の中での理解としては、Class クラスのオブジェクトを生成し Post というグローバルな定数へ代入している。
なので、以下の2つの記述は同じ意味だ。
class Post def hello puts 'hello' end end post = Post.new post.hello #=> helloPost = Class.new do def hello puts 'hello' end end post = Post.new post.hello #=> hello定数 Post に入っている Class クラスのオブジェクトへ特異メソッドを定義してみる。
Post = Class.new do def hello puts 'hello' end end def Post.bye puts 'good bye' end Post.new.hello #=> hello Post.bye #=> good byePost.bye という呼出しができた。これはクラスメソッドの呼出しと同じ。
つまり、クラスメソッド Post.bye というのは、Post に入っている Class クラスのオブジェクトへの特異メソッドの定義として読むことができる。これにオブジェクトの特異クラスの引き出しの記法 << をあわせて考えると、一番冒頭のコードでやろうとしていることがわかってくる。
特異クラス
クラスメソッドの定義は特異メソッド形式と特異クラス形式があった。
特異メソッド形式で定義した def Post.bye を特異クラス形式へ書きかえてみる。
Post = Class.new do def hello puts 'hello' end end class << Post def bye puts 'good bye' end end Post.new.hello #=> hello Post.bye #=> good byeさらに書き換えると下記にようになる
class Post def hello puts 'hello' end class << self def bye puts 'good bye' end end end Post.new.hello #=> hello Post.bye #=> good byeクラスメソッドのための記法があるわけではなく、特異メソッドという仕組みを使って巧みにクラスメソッドが実現されていることがわかった。
おわりに
今まで何気なく使っていたself。
というかなんとなく理解できたようでできていなかった部分だった。私が参考にした、というかこの記事はほぼ下記の記事のコピペなので、私の記事がわかりにくかったという方は、ぜひ下のURLの記事を参考にして欲しい。
参考記事
https://magazine.rubyist.net/articles/0046/0046-SingletonClassForBeginners.html
- 投稿日:2020-04-04T21:45:47+09:00
CatalinaにアップグレードしたmacでrbenvからRuby 2.7.1をインストールしようとしたらgmpが読み込めずに失敗した
CatalinaにアップグレードしたmacでrbenvからRuby 2.7.1をインストールしようとした。
$ rbenv install 2.7.1 ... dyld: Library not loaded: /usr/local/opt/gmp/lib/libgmp.10.dylib Referenced from: /var/folders/p9/38jx3_ks5zb3ml70pccx4g440000gn/T/ruby-build.20200404201643.64758.NBfaXF/ruby-2.7.1/ruby Reason: image not found make: *** [rdoc] Abort trap: 6で失敗する。
$ ls /usr/local/opt/gmp/lib/ ls: /usr/local/opt/gmp/lib/: No such file or directory見てみると当該ディレクトリにはなにもない。
しかしインストールしようとするとインストール済みと言われる。$ brew install gmp Updating Homebrew... Error: gmp 6.1.2_2 is already installed To upgrade to 6.2.0, run `brew upgrade gmp`.アップグレードしてみる
$ brew upgrade gmp Updating Homebrew... ==> Upgrading 1 outdated package: gmp 6.2.0 ==> Upgrading gmp -> 6.2.0 ==> Downloading https://homebrew.bintray.com/bottles/gmp-6.2.0.catalina.bottle.tar.gz ==> Downloading from https://akamai.bintray.com/2e/2e6acd6e62d1b8ef0800061e113aea30a63f56b32b99c010234c0420fd6d3ecf?__gda__=exp=1586003712~hmac=1a3ede8872bae9e8bd6b238be3e7c56d1cc64a5b770646c6ffe342d6da269809&response-content-disposition=attachment%3Bfilename%3D%22gmp-6.2.0.catalina.bottle.tar.gz%22&response-content-type=application%2Fgzip&requ ######################################################################## 100.0% ==> Pouring gmp-6.2.0.catalina.bottle.tar.gz ? /usr/local/Cellar/gmp/6.2.0: 20 files, 3.2MB Removing: /usr/local/Cellar/gmp/6.1.2_2... (18 files, 3.1MB)見てみたら先程のディレクトリにもちゃんとファイルができた。
$ ls /usr/local/opt/gmp/lib/ libgmp.10.dylib libgmp.a libgmp.dylib libgmpxx.4.dylib libgmpxx.a libgmpxx.dylib pkgconfig再度Rubyをインストール
$ rbenv install 2.7.1 Downloading ruby-2.7.1.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2 Installing ruby-2.7.1... ruby-build: using readline from homebrew Installed ruby-2.7.1 to /Users/niwatako/.anyenv/envs/rbenv/versions/2.7.1成功。
- 投稿日:2020-04-04T21:17:04+09:00
rails 通知機能
はじめに
今回は通知機能を作成しました。
こちらの記事を参考にさせていただいております。
https://qiita.com/nekojoker/items/80448944ec9aaae48d0a
https://qiita.com/yuto_1014/items/2db1dd4fcd7945b980f7作るもの
コメント・いいね・フォローされた時に通知を作成して確認・削除できる機能を作成します。すでに上記の機能はあるものとして作成してます。どれか一つでも機能があればOK。参考に過去に投稿したコメント・フォロー機能についてリンクを載せておきます。
コメント機能:https://qiita.com/E6YOteYPzmFGfOD/items/ef776d34908872ea19f7
フォロー機能:https://qiita.com/E6YOteYPzmFGfOD/items/ec0492b509962c3b7ae4ER図
参考に今回作成する通知機能のER図です。(今回関係ないタグ機能がありますが無視してください。)
作成の流れ
1.Notificationモデルの作成
2.各モデルの関連づけ
3.通知メゾットの作成
4.通知機能をコントローラーへ埋め込む
5.通知一覧画面と通知削除作成モデルの作成
rails g model Notification visitor:references visited:references micropost:references comment:references action:string checked:booleandb/migrate/class CreateNotifications < ActiveRecord::Migration[5.1] def change create_table :notifications do |t| t.references :visitor, foreign_key:{ to_table: :users }, null: false t.references :visited, foreign_key:{ to_table: :users }, null: false t.references :micropost, foregin_key: true t.references :comment, foregin_key: true t.string :action, null: false t.boolean :checked, null: false, default: false t.timestamps end end endvistor_id
→通知するユーザー(いいね、コメント、フォローする側)
visted_id
→通知をうけるユーザー
rails g model カラム名:references とすると自動で
・カラム名にidをつけた形でカラムを作成。
・インデックス付与。
foreign_key:true
・外部キー制約を付与
to_table: :user
・visitorとvisitedカラムの参照テーブルを指定してます。
nul: false
・空の状態で保存できなくする。モデルの関連付け
app/models/user.rbhas_many :active_notifications, foreign_key:"visitor_id", class_name: "Notification", dependent: :destroy has_many :passive_notifications, foreign_key:"visited_id", class_name: "Notification", dependent: :destroyapp/models/micropost.rbhas_many :notifications, dependent: :destroyapp/models/comment.rbhas_many :notifications, dependent: :destroyapp/models/notification.rbclass Notification < ApplicationRecord default_scope -> { order(created_at: :desc) } belongs_to :visitor, class_name: "User", optional: true belongs_to :visited, class_name: "User", optional: true belongs_to :micropost, optional: true belongs_to :comment, optional: true validates :visitor_id, presence: true validates :visited_id, presence: true ACTION_VALUES = ["like", "follow", "comment"] validates :action, presence: true, inclusion: {in:ACTION_VALUES} validates :checked, inclusion: {in: [true,false]} end各オプション
foreign_key:"vistor_id", class_name: "Notification"
→関連づけるカラム名とテーブル名を指定します。
dependent: :destroy
→投稿が削除された際に関連付いている通知を削除。
default_scope -> { order(created_at: :desc) }
→通知が新しい順に並ぶ。
optional: true: nullの値を許可する。
inclusion
→保存できる値を制限しています。通知メゾットの作成
いいね
app/models/micropost.rbdef create_notification_like!(current_user) temp = Notification.where(["visitor_id = ? and visited_id = ? and micropost_id = ? and action = ? ", current_user.id, user_id, id, 'like']) if temp.blank? notification = current_user.active_notifications.new( micropost_id: id, visited_id: user_id, action: 'like' ) if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? end end始めに通知が作成済みでないか確認してます。(何度も作成しないように)登録済みの場合と自分の投稿に対するいいねの場合は通知を確認済みとして作成します。(checkedをtrueにする。)active_notificationsはuserモデルでhas_many関連付けを行った際に名付けた関連名です。
コメント
app/models/micropost.rbdef create_notification_comment!(current_user, comment_id) #同じ投稿にコメントしているユーザーに通知を送る。(current_userと投稿ユーザーのぞく) temp_ids = Comment.where(micropost_id: id).where.not("user_id=? or user_id=?", current_user.id,user_id).select(:user_id).distinct #取得したユーザー達へ通知を作成。(user_idのみ繰り返し取得) temp_ids.each do |temp_id| save_notification_comment!(current_user, comment_id, temp_id['user_id']) end #投稿者へ通知を作成 save_notification_comment!(current_user, comment_id, user_id) end def save_notification_comment!(current_user, comment_id, visited_id) notification = current_user.active_notifications.new( micropost_id: id, comment_id: comment_id, visited_id: visited_id, action: 'comment' ) if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? endコメントの場合は同じ投稿に対してコメントしているユーザーにもコメントを送るようにします。マイクロポストの投稿者には必ず通知が1件作成されるようにします。
「where.(micropost_id: id)」
→同じ投稿にコメント
「where.not("user_id=? or user_id=?", current_user.id,user_id)」
→コメントしたユーザーと投稿者は除く。
distinct
→複数回コメントしている人も通知は一件のみにする
select(:user_id)
→user_idのみ取得しています。取得したuser_idを下で定義している通知作成メゾットに渡して繰り返し通知を作成します。
フォロー
app/models/user.rbdef create_notification_follow!(current_user) #すでに通知が作成されているか確認 temp = Notification.where(["visitor_id = ? and visited_id = ? and action = ? ",current_user.id, id, 'follow']) if temp.blank? notification = current_user.active_notifications.new( visited_id: id, action: 'follow' ) notification.save if notification.valid? end end通知機能を各コントローラーへ埋め込み
各通知メゾットをコメント等のアクションを起こした際に起動するようにコントローラー内へ埋め込んでいきます。
コメント
app/controlloers/comments_controller.rbdef create @comment = current_user.comments.build(comment_params) @comment.micropost_id = params[:micropost_id] if @comment.save flash[:success] = 'コメントしました' #通知機能用 @micropost=@comment.micropost @micropost.create_notification_comment!(current_user, @comment.id) #ここまで通知機能 redirect_to @comment.micropost else comments_get render template: 'microposts/show' endフォロー
app/controllers/follow_controlloer.rbdef create @user =User.find(params[:follow_relationship][:following_id]) current_user.follow(@user) #通知機能追加 @user.create_notification_follow!(current_user) respond_to do |format| format.html {redirect_back(fallback_location: root_url)} format.js end endいいね
app/controllers/like_controlloer.rbdef create @user = current_user @micropost = Micropost.find(params[:micropost_id]) current_user.like(@micropost) #通知機能追加 @micropost.create_notification_like!(current_user) respond_to do |format| format.html { redirect_back(fallback_location: root_url) } format.js end end通知一覧画面と通知削除作成
まずは通知ページ表示ようのコントローラ、ルーディングの設定です。
rails g controller notificationsconfig/routes.rbresources :notifications, only: [:index, :destroy]app/controllers/notifications_controlloer.rbdef index @notifications = current_user.passive_notifications #通知画面を開くとcheckedをtrueにして通知確認済にする @notifications.where(checked: false).each do |notification| notification.update_attributes(checked: true) end end def destroy @notifications =current_user.passive_notifications.destroy_all redirect_to notifications_path end続いて通知一覧画面の作成です。
app/views/notifications/index.html.erb<h3 class="text-center">通知</h3> <%= link_to "通知削除", notification_path(@notifications), method: :delete ,class: "fas fa-trash" %> <% if @notifications.exists? %> <div class="notification-index"> <%= render @notifications %> </div> <% else %> <p>通知はありません</p> <% end %>app/views/notifications/_notification.html.erb<div class="notification-view"> <%= notification_form(notification) %><span class="moderate-font"><%= " (#{time_ago_in_words(notification.created_at)}前)" %></span> <br> <% if !@comment.nil? %> <p class="notification-comment"><%= @comment %></p> <% end %> </div>いいね、フォロー、コメントの通知によって表示する内容を変更するために、
ヘルパーメゾットを作成してviewで呼び出します。ruby/app/helprs/notifications_helper.rbmodule NotificationsHelper def notification_form(notification) #通知を送ってきたユーザーを取得 @visitor = notification.visitor #コメントの内容を通知に表示する @comment = nil @visitor_comment = notification.comment_id # notification.actionがfollowかlikeかcommentかで処理を変える case notification.action when 'follow' #aタグで通知を作成したユーザーshowのリンクを作成 tag.a(notification.visitor.name, href: user_path(@visitor)) + 'があなたをフォローしました' when 'like' tag.a(notification.visitor.name, href: user_path(@visitor)) + 'が' + tag.a('あなたの投稿', href: micropost_path(notification.micropost_id)) + 'にいいねしました' when 'comment' then #コメントの内容と投稿のタイトルを取得 @comment = Comment.find_by(id: @visitor_comment) @comment_content =@comment.content @micropost_title =@comment.micropost.title tag.a(@visitor.name, href: user_path(@visitor)) + 'が' + tag.a("#{@micropost_title}", href: micropost_path(notification.micropost_id)) + 'にコメントしました' end end以上となります。
だいぶ長くなりましたがここまでお読みいただきありがとうございました!!
- 投稿日:2020-04-04T20:35:54+09:00
Ruby 基礎知識
Ruby基礎知識
to_sメソッド
オブジェクトの内容を文字列化するメソッド
rubyputs 1.to_s + 7.to_s #=> "17" puts 'nil'.to_s #=> ""
to_iメソッド
文字列表記から整数表記へ変換するメソッド
rubystr = "23" puts str.to_i + 12 #=> 35
to_fメソッド
整数表記から小数表記へ変換するメソッド
rubyn = 5 puts n.to_f #=>5.0 puts n.to_f / 2 #=>2.5
メソッドの呼び出し
オブジェクト.メソッド(引数)
*()は省略可ruby#数値を16進数の文字列に変換 puts 14.to_s(16) #=> "e" puts 14.to_s 16 #=> "e"
コメントの入れ方
ruby# 1行の場合(文の途中からでも可) =begin 複数行 コメント 可 =end
文字列に変数を組み込む
rubyage = 24 puts "私の年齢は" + age + "歳です" #=>エラー puts "私の年齢は #{age} 歳です" #=>私の年齢は24歳です puts "私の年齢は" + age.to_s + "歳です" #=>私の年齢は24歳です
sprintfメソッド
rubysprintf('%0.3.f', 1.2) #=> "1.200"
- 投稿日:2020-04-04T20:18:24+09:00
【VScode】なぜか自動保存できねえ時の解決法、そしてパーミッション関連のことも【備忘録】
【VScode】なぜか自動保存できねえ時の解決法
設定でAfterdelayなどにしてファイルの自動保存機能をつけているVScodeで開発しているときに、
以下のようなエラーが出て、自動が保存ができないような事態の解決法を紹介します
[アクセス権限が不十分です。[Sudo 権限で再試行]を選択してスーパーユーザーとして再試行してください。]
と出ております。
つまり、現在、Sudoユーザーとして、ファイルにアクセスできていない状態なので、
・スーパーユーザーにモードを変える
・ファイル、あるいはフォルダのアクセス権限(パーミッション)を変更する
方法があります。今回は後者の手段を用いて、このエラーを解決します。
terminalsudo chmod -R 777 ファイルのディレクトリ位置(Ex. /Users/kazuhitoNakayama/Desktop/index.html.erb)この一行で、全てのユーザーに対してのファイルの実行権限を与えられるので、
上記エラーが解決されます。解説
chmodとは
?ファイルやディレクトリのアクセス権限を変更する際に使うコマンドです
(UNIX系のOSで使用できます。Ex.Macなど)使い方は、chmod [オプション] [与える権限] [対象のファイル、ディレクトリのディレクトリ位置]
オプションは私は普段 「-R」を使ってますが、他にもたくさんあるので
「chmod オプション」とかでお調べください!777とは
?先ほどchmod [オプション] [与える権限] [対象のファイル、ディレクトリのディレクトリ位置]
とお伝えしました。
ここでの[与える権限]について説明すると、アクセス権の記法には2種類あり、
・アルファベット
・数字
があります。アルファベットでの記法
あるフォルダの中に入って「ls -l」をすることで、各ファイルの権限を参照できるので、みてみると、
アルファベットの羅列が見えます。terminal$ ls -l drwxr-xr-x 2 user_name group 68 8 30 15:53 css -rw-r--r-- 1 user_name group 0 8 30 15:53 index.htmlそれぞれの文字は
r:(read)読み込み権限
w:(write)書き込み権限
x:(execute)実行権限
こんな風に対応しております。例えば上の、drwxr-xr-xをいかに読むかというと
d/rwx/r-x/r-x
↑こんな風に区切られます。また、それぞれの区切りの中で、
ディレクトリなのかファイルなのか/所有者に対する権限/グループに対する権限/その他の者に対する権限/
という風に区切られており、それぞれの対象に対して、権限をr・w・xで与えます。
(1文字目に関してはdならば当該ファイルはディレクトリとわかります。-ならばファイルです。)よって、
d/rwx/r-x/r-xは
ーディレクトリであり
ー自分に対して、読み込み、書き込み、実行の全ての権限が与えられており、
ーグループに対して、読み込み、実行権限が与えられており、
ーその他の者に対して、読み込み、実行権限が与えられています。数字の記法
シンプルで、上記、r・w・xがそれぞれ数字に変わるだけですね!
r(読み込み権限):4
w(書き込み権限):2
x(実行権限):1そして今回は3つの数字で権限対象、与える権限を表現します
例えば、7311つ目の数字:所有者
2つ目の数字:グループ
3つ目の数字:その他の者
という風になっているので、731は、
所有者は、7=4+2+1なので読み込み、書き込み、実行権限が与えられ、
グループは、3=2+1なので書き込み、実行権限が与えられ、
その他の者は、1なので実行権限が与えられます。総括
冒頭の振り返りで行くと
terminalsudo chmod -R 777 ファイルのディレクトリ位置(Ex. /Users/kazuhitoNakayama/Desktop/index.html.erb)これによりindex.html.erbのファイルのパーミッションを、誰でも実行できるようにしたので、自分がファイルを変更してもパーミッションで怒られることがなくなったのです!
パーミッションは自分的に忘れやすい!
必覚!
- 投稿日:2020-04-04T18:45:40+09:00
素人がWebサービスを自分で作る備忘録(前準備編)1
この記事の目的
この記事は自分が初めてWebサービスを作るにあたっての備忘録的な意味合いが強いです。
その為、エンジニアリング経験者の方にとっては特に為になる内容ではないと思われますが、ズブの素人が初めてサービスを開発しようと思ってからの成長日記だと思って見てもらえると嬉しいです。また、同じような未経験者の方がWebサービスを開発しようとしたとき、何かの手助けになれれば嬉しいと思います。
現在のレベル
・Progate学習済み(HTML&CSS、Javascript、React、Ruby、RubyonRails、Git、CommandLine、SQL)
・Railsチュートリアル 二周個人でWebサービスを作る際にはまず、何のために作るのか決めそれに適した基礎知識を習得する必要が出てきます。
今回は、第一の目標として今まで学習してきた内容のアウトプット、第二の目標はモダンなIT企業へのジョブチェンジするためのポートフォリオ作成ということで行っていきます。
その為、Web業界で今現在多く使われているRailsを選択しました。
Rails学習のバイブルとして多くに人に利用されているRailsチュートリアルですが、これを内容を理解するためには学習のための学習が必要となってくる(Reactを除く)。その学習にはProgateがおすすめ!Webサービスの企画
上記の学習を終えたところで実際に、Webサービスの開発に入っていきます
しかし、いきなりコードを書けと言われて書くことはできないはずです!なぜなら何を作ろうとか、どのような機能を持たせようとか、そういったところの話を先にやらないと作れるわけがないんです!1. 何のために作成するのか
2. どのような物を作るのか
3. どういった機能を盛り込むのかこのようなところから考えていきたいと思います。
1に関しては上でも書いた通り、知識のアウトプット、ポートフォリオ作成です。
2に関しては
・今まで学んだ知識 +αで作れる物(大きなことを言うと後で後悔しそうなので)
・未経験からの転職で有利になりそうな機能を実装すること
・自分が作りたい物(コロナとかで外に出れないので他の人と繋がれるサービスとか)を条件とします。
3に関しては・ユーザー管理機能
・投稿機能
・投稿一覧、投稿詳細機能
・画像ファイルアップロード機能
・ページネーション機能or無限スクロール機能
・DBテーブルのリレーション管理
・単体、統合テスト
+αの内容
・ReactによるJavascriptライブラリ
を取り入れていこうと思います。次では具体的なサービスの形を考えていくことについて書いていこうと思います。
- 投稿日:2020-04-04T18:45:40+09:00
素人がWebサービスを自分で作る備忘録(前準備編)
この記事の目的
この記事は自分が初めてWebサービスを作るにあたっての備忘録的な意味合いが強いです。
その為、エンジニアリング経験者の方にとっては特に為になる内容ではないと思われますが、ズブの素人が初めてサービスを開発しようと思ってからの成長日記だと思って見てもらえると嬉しいです。また、同じような未経験者の方がWebサービスを開発しようとしたとき、何かの手助けになれれば嬉しいと思います。
現在のレベル
・Progate学習済み(HTML&CSS、Javascript、React、Ruby、RubyonRails、Git、CommandLine、SQL)
・Railsチュートリアル 二周個人でWebサービスを作る際にはまず、何のために作るのか決めそれに適した基礎知識を習得する必要が出てきます。
今回は、第一の目標として今まで学習してきた内容のアウトプット、第二の目標はモダンなIT企業へのジョブチェンジするためのポートフォリオ作成ということで行っていきます。
その為、Web業界で今現在多く使われているRailsを選択しました。
Rails学習のバイブルとして多くに人に利用されているRailsチュートリアルですが、これを内容を理解するためには学習のための学習が必要となってくる(Reactを除く)。その学習にはProgateがおすすめ!Webサービスの企画
上記の学習を終えたところで実際に、Webサービスの開発に入っていきます
しかし、いきなりコードを書けと言われて書くことはできないはずです!なぜなら何を作ろうとか、どのような機能を持たせようとか、そういったところの話を先にやらないと作れるわけがないんです!1. 何のために作成するのか
2. どのような物を作るのか
3. どういった機能を盛り込むのかこのようなところから考えていきたいと思います。
1に関しては上でも書いた通り、知識のアウトプット、ポートフォリオ作成です。
2に関しては
・今まで学んだ知識 +αで作れる物(大きなことを言うと後で後悔しそうなので)
・未経験からの転職で有利になりそうな機能を実装すること
・自分が作りたい物(コロナとかで外に出れないので他の人と繋がれるサービスとか)を条件とします。
3に関しては・ユーザー管理機能
・投稿機能
・投稿一覧、投稿詳細機能
・画像ファイルアップロード機能
・ページネーション機能or無限スクロール機能
・DBテーブルのリレーション管理
・単体、統合テスト
+αの内容
・ReactによるJavascriptライブラリ
を取り入れていこうと思います。Webサービスの見た目を考える
Webサービスの見た目を考える場合、誰をターゲットにするのか、どのような場面で使われるのかなどを考えて機能やページデザインを考える物です。
しかし、今回は完全に自分のためのものですのでその辺は深く考えずやっていきたいと思います。(はやく実装に進みたいので)とりあえず
ターゲット:20代 外出自粛させられているせいで友達と遊べなくて暇を持て余している。ページデザインは適当にサックリ手書きで紙に書きました。(早く実装にすすみt)
画面遷移図も手書きでさっくり(早くz)データベーススキーマ設計も手書きで作成。
※データベーススキーマ設計は私にとって初めて聞くものだったので次の記事にてもう少しまとめたいと思います。ここまで行ったこと
・基礎学習
・作るWebサービスの企画
なぜ作るのか
どのような物を作るのか
どういった機能が必要なのか
・Webサービスの見た目を簡単に設計
モックアップの作成
画面遷移図の作成
データベーススキーマ設計
- 投稿日:2020-04-04T18:26:19+09:00
【Rails】enum_helpを用いてセレクトボックスを作成
はじめに
こんな感じのフォームを作ります。
観測した限りでは一番シンプルな書き方です。問題などございましたらご指摘をお願いします。環境
ruby 2.5.3
Rails 5.2.4.2
enum_help (0.0.17)
rails-i18n (5.1.3)作成法
enumの設定
models/user.rbclass User < ApplicationRecord validates :name, presence: true, length: { maximum: 30 } validates :description, length: { maximum: 300 } validates :privacy, presence: true enum privacy: { published: 0, closed: 1 } endbooleanにしていないのは、今後限定公開などの機能を追加することを想定しているためです。
このようにenumを設定することで、データベースでは数値の値を文字列として擬似的に扱うことができます。
また、この値は文字列でもシンボルでも指定することができます。user.privacy => "closed" user.privacy = 0 => 0 user.privacy => "published" user.privacy = :closed => :closed user.privacy => "closed"i18nの設定
Gemfilegem 'rails-i18n' gem 'enum_help'必要なgemを記述して、
$ bundle install
でインストールします。
そして、application.rbに以下の設定を追加します。config/application.rbmodule TestApp class Application < Rails::Application # 言語・タイムゾーンを日本に設定 config.i18n.default_locale = :ja config.time_zone = 'Tokyo' config.active_record.default_timezone = :local # config/locales/配下の全てのrb, ymlファイルを読み込み対象とする config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] end end
config/locales
配下に日本語化用のファイルを用意します。(ファイルの場所や名前は自由)config/locales/models/ja.ymlja: activerecord: models: user: ユーザー attributes: id: ID created_at: 作成日時 updated_at: 更新日時 user: name: 名前 description: 自己紹介 privacy: 公開設定 enums: user: privacy: published: 公開 closed: 非公開formの作成
form.html.slim= form_with model: @user, local: true do |f| = f.label :name = f.text_field :name br = f.label :description = f.text_area :description br = f.label :privacy = f.select :privacy, User.privacies_i18n.invert br = f.submitこんな感じです。ポイントはセレクトボックスの値です。
= f.select プロパティ名, 選択肢の配列
とすればいいので、= f.select :privacy, [['公開', 0], ['非公開', 1]]これでも可能ですが、なんか嫌です。モデルと関連付けたい。
そこで、gemの出番です。'enum_help'
によってそれぞれ以下のようなインスタンスメソッドとクラスメソッドが使えるようになります。user.privacy_i18n => "公開" User.privacies_i18n => {"published"=>"公開", "closed"=>"非公開"}これを利用して
[[表示される選択肢, 渡される値], [表示される選択肢, 渡される値]]
の形の配列に置き換えます。User.privacies_i18n.map { |k, v| [v, k] } => [["公開", "published"], ["非公開", "closed"]] User.privacies_i18n.invert.to_a => [["公開", "published"], ["非公開", "closed"]]どちらも同じですが、後者の方が文字数が少なくシンプルかなと思います。
(追記)
これだけ書いておいて何ですが、配列に変更する必要はありませんでした。ハッシュのままでも行けました。
ということで、User.privacies_i18n.invert
が最短です。
そして五年前の記事で既に言及していたので、ここに恥を晒しておきます。リンク
Enums | Active Record クエリインターフェイス - Railsガイド
Rails 国際化 (i18n) API - Railsガイド
- 投稿日:2020-04-04T17:52:05+09:00
Rails6.0でYoutubeDataAPIv3を使う
プログラミングの練習がてら、愛しのホロライブのチャンネル、動画情報をyoutubeのapiを利用して表示しようと思ったときに、以前YoutubDataAPIを利用した時と勝手が変わっていたので、改めて実装方法を備忘として残しておこうと思います。
開発環境
- CentOS 7.6
- Ruby 2.5.3
- Ruby on Rails 6.0
準備
APIキーを取得する
APIを利用するためにはAPIキーを準備する必要があります。
これはこれで説明がいるほどめんどくさいのですが、ググればいくらでも出てきますので調べてみてください。説明するのがめんどくさいわけではないです。説明するのがめんどくさいわけではないです。一応良さそうな記事をお借りさせていただきます。
YouTube APIキーの取得 (2020/03/25時点)Gemをインストールする
Railsプロジェクトの中のGemfileの中に以下を追記してbundle installする。
Gemfilegem 'google-api-client'(必要があれば) 環境変数の設定をする
APIキーを使うとyoutubeのパーソナルな情報が利用できるのですが、逆に言うと悪用すると他人のパーソナルな情報を引き出せるということになるので、GitHubなどにソースをコミットした時に意図せずAPIキーを公開してしまわないように別で管理する必要があります。
というわけで、環境変数を利用してコミットされるソースの外側でAPIキーを管理します。
ただしAPIを触るというだけなら必要ない手続きになるので、必要のない方はスルーしてください。まずは以下のをGemfileに以下のコードを記述し、bundle installする。
Gemfilegem 'dotenv-rails'こちらのGemは環境変数を利用しやすくしてくれる優れものです。
次にAPIキーを管理するファイルを用意します。
.gitignoreというファイルと同じところ(おそらくプロジェクトの直下)に.envファイルを作成し、中にAPIキーの情報を記入します。.envYOUTUBE_DATA_API_KEY=APIキー管理ファイルを作成したらそのファイルをコミットの対象外にします。
.gitignoreファイルに設定するとそのファイルはコミット対象外になるので、.envを追記します。.gitignore# 追記 .envこれで環境変数の準備完了です。
いざ
YoutubeDataAPIに接続するためのインスタンスを準備
APIを使うたびにインスタンスを生成する必要はないので、イニシャライザーで生成します。というわけで/config/initializersディレクトリにそれ用のファイルを作成します。ファイル名は仮にyoutube.rbとします。
/config/initializers/youtube.rbrequire 'google/apis/youtube_v3' API_KEY = ENV['YOUTUBE_DATA_API_KEY'] def get_youtube_service service = Google::Apis::YoutubeV3::YouTubeService.new service.key = API_KEY return service endこれでAPIにアクセスできるインスタンスを取得できるメソッドが用意できました。
ちなみに環境変数設定をしていない方は、ENV['YOUTUBE_DATA_API_KEY']の個所をAPIキーに置き換えてください。ようやっと使用。
お使いのコントローラー等で、先ほど用意したメソッドでインスタンスを取得し、用意されたメソッドで情報を持ってきます。下記ではチャンネル情報を取得しています。
使用例# インスタンスを取得 youtube = get_youtube_service #APIに接続して、目的の情報を取得する channel_data = youtube.list_channels("snippet,brandingSettings", id: "UCDqI2jOz0weumE8s7paEk6g") #インスタンスに情報を詰める @member = Member.new channel = channel_data.items.first snippet = channel.snippet branding_settings = channel.branding_settings @member.channel_id = channel.id @member.channel_name = snippet.title @member.icon = snippet.thumbnails.high.url @member.banner = branding_settings.image.banner_image_url return @member@memberのモデル構造は察してください。
今回は我が愛しのロボ子さんのチャンネル情報を取得しました。
取ってきた情報は結構な入れ子構造になっていて、そこんとこをわかっておかないと利用するのは結構きついです。具体的な話は公式のリファレンスを参照するのがいいと思うのでそちらをご確認ください。
ただし若干情報が古いらしく、たまに使えない箇所があります。
公式リファレンスチャンネル情報以外の情報を取るときは、今回イニシャライザーでrequiredしている'google/apis/youtube_v3'のソースを直接参照するのが速いと思います。
(他にいいやり方があれば是非教えてください。。。)
OSごとに保存先は違うとは思いますが、私自身の備忘も兼ねて参考程度に載せておくと以下のようになります。
/home/(ユーザー)/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/google-api-client-0.37.2/generated/google/apis/youtube_v3/service.rb以上です。
何か不備があればコメントやご連絡をいただけますと幸いです。
- 投稿日:2020-04-04T17:02:07+09:00
【備忘録】カラムとプロパティの違いについて
はじめに
カラムとプロパティって言葉でてきて混乱したのでめっちゃ簡単にまとめてみました~?
カラムとプロパティの違い?
カラム:データーベース側の呼び方
プロパティ:サーバーサイド側の呼び方
結論:呼び方が違うだけで大体一緒のこと
カラムちょっと詳しく?
画像(データーベース)の id や user_id 、 name などのこと。
プロパティちょっと詳しく?
例:form_for<%= form_for @user do |form| %> <%= form.label :name %> <%= form.text_field :name %> <%= form.label :address %> <%= form.text_area :address %> <%= form.submit %> <% end %>このようなフォームを作るときに出てくる
<%= form.text_field :name %> <%= form.text_area :address %>この部分の :name 、 :address のこと
さいごに
form.text_fieldの引数に、『カラム名を指定する』っていうのはあまり正しくなくて、『プロパティを指定する』っていうのが正しいみたいです~?
- 投稿日:2020-04-04T14:15:52+09:00
【Rails】現場Railsメモ
執筆中
- 復習
- アウトプット前提のインプット
環境
Ruby 2.6.5
Rails 5.2.4.2
MySQL 5.7.28
Chapter1 RailsのためのRuby入門
オブジェクト
- 言葉によって区別できるあらゆる「モノ」
- 全てのオブジェクトは
object_id
という固有番号をもち、固有の存在として認識される- 仕事は何らかの振る舞い(メソッド)をすること
クラス
- オブジェクトの原型になるもの(設計図)
人間
太郎くん
花子さん
hogeくん
fugaくん人間がクラスに該当。
インスタンス
- クラスを元に作成された実態
人間
太郎くん
花子さん
hogeくん
fugaくん人間未満(言葉不適切?)がインスタンスに該当。
変数
- 何かのオブジェクトをさし示すことができる、ラベルのような存在
ローカル変数
- プログラム中の一定の処理の範囲で使われ、その範囲が終わったら捨てられる
インスタンス変数
- オブジェクトの内部に保持されてオブジェクトが存在する限り一緒に存在する
メソッド
- オブジェクトの何らかの振る舞い
- クラスメソッドとインスタンスメソッド
人間
- 名前
- 体
- 喜怒哀楽太郎くん
- 1秒間にタイピングを10回打てる
花子さん
- 3桁の数字の15個の和を2秒で求められる
hogeくん
- 100mを9.58で走れる
fugaくん
- 1時間で料理を10品作れる人間クラスのインスタンスである4人は
歩く、食べる、笑う
ことができる。
名前、体、喜怒哀楽
がクラスメソッドに該当。人間クラスのインスタンスである4人のそれぞれにしかできない
特殊能力がインスタンスメソッドに該当。レシーバー
- メソッドを呼ぶ元のオブジェクト
hoge = 'ほげ'
hoge.length
hoge.class
hoge.length
のhoge
がレシーバーに該当。
.length
はStringクラス
(前述の人間クラス)がもつメソッドに該当。返り値(戻り値)
- メソッドが呼ばれた時に帰ってくる値のこと
属性(Attribute)
- オブジェクトの抱えるデータ
1-4~スタート
Chapter3 タスク管理アプリケーションを作ろう
テンプレートエンジン
- HTMLの構造が直感的にわかりやすいテンプレート
ERBやHamlやSlim
Strong Parameters
- 想定しているリクエストパラメーターのみ受け取る仕組みのこと
flashとflash.nowの違い
- flash → 次のリクエストに対してデータを伝える → redirect
- flash.now → 同じリクエスト内で伝えることができる → render
simple_format
- 入力時の改行を、表示させる時に改行としてviewに表示させることを可能にする
Chapter4 現実の複雑さに対応する
環境別rails db:migrate
ターミナル# 開発用 $ rails db:migrate # テスト用 $ rails db:migrate RAILS_ENV=test # 本番用 $ rails db:migrate RAILS_ENV=productionchange_cloumn_null
- 既存テーブルの既存カラムのNOT NULL制約をつけたり外したりできる
共同開発を意識し、今後は
rails db:rollback
は極力使用しないようにするターミナル$ rails g migration Changeテーブル名NameNotNulldb/上記コマンドによって生成されるマイグレーションファイルdef change change_column_null :テーブル名, :カラム名, false or true endオリジナルの検証コード(重要)
- P141~142
本書ではカンマを許可しないメソッドを実装
コールバック
- 登録や削除などの重要なイベントの前後に任意の処理を挟むことができる仕組み
然るべきタイミングが来たら処理を呼ぶことができる
トランザクション
- 一連の複数の処理によるデータベースの生合成を保つための機能
セッション
- 1つのブラウザから
- 連続して送られている複数のリクエストの間で
- ブラウザとサーバーで共有したい「情報」を
- サーバー側に保存する仕組み
Cookie
- 1つのブラウザから
- 連続して送られている複数のリクエストの間で
- ブラウザとサーバーで共有したい「情報」を
- ブラウザ側に保存する仕組み
digest
- ハッシュ化を行った文字列
パスワードの保存時に使用
ハッシュ化
- 元の値に戻すことができない一方的な変換
Userモデルにadminフラグを追加
マイグレーションファイルdef change add_column :users, :admin, :boolean, default: false, null: false end
:boolean, default: false
でadminカラムに0が入る?
データ取得時にはtrue
orfalse
が入っているtrue or falseの言語化?
ターミナル$ rails c user1 = User.first user1.admin → false user2 = User.find(2) user2.admin → true user1.admin? ? '権限あり' : '権限なし' → 権限なし user2.admin? ? '権限あり' : '権限なし' → 権限あり
? 'true(1)時の表示' : 'false(0)時の表示'
- 投稿日:2020-04-04T12:53:10+09:00
【Rails】Ajaxを用いた非同期いいね機能の実装
目標
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina前提
ログイン機能、投稿機能を実装済み。
いいね機能の実装
テーブル
usersテーブル
カラム データ型 name string introduction text profile_image_id string booksテーブル
カラム データ型 title string body text book_id integer user_id integer favoritesテーブル
カラム データ型 user_id integer book_id integer モデル
user.rbhas_many :favorites, dependent: :destroy def favorited_by?(book) favorites.where(book_id: book.id).exists? endbook.rbhas_many :favorites, dependent: :destroyfavorite.rbbelongs_to :user belongs_to :bookルーティング
routes.rbresources :books do resource :favorites, only: [:create, :destroy] endコントローラー
favorites.controll.rbclass FavoritesController < ApplicationController def create @book = Book.find(params[:book_id]) # いいねボタンを連打しても1回しかいいね出来ない様に条件をつける unless current_user.favorited_by?(@book) favorite = current_user.favorites.new(book_id: @book.id) favorite.save redirect_to @book end end def destroy @book = Book.find(params[:book_id]) favorite = current_user.favorites.find_by(book_id: @book.id) favorite.destroy redirect_to @book end endビュー
1.
投稿一覧
をパーシャル化books/index.html.erb<% @books.each do |book| %> <tr> <%= render 'books', book: book %> </tr> <% end %>3. showページ等でもいいねボタンを使い回したいので、さらに
いいねボタン
をパーシャル化books/_books.html.erb<td> <%= render 'favoritebutton', book: book %> </td>4.
いいねボタン
を作成books/_favoritebutton.html.erb# current_userがその投稿をいいねしているかによって表示を変えている <% if book.favorited_by?(current_user) %> <%= link_to book_favorites_path(book), method: :delete, remote: true do %> <i class="fa fa-heart" aria-hidden="true" style="color: red;"></i> <%= book.favorites.count %> <% end %> <% else %> <%= link_to book_favorites_path(book), method: :post, remote: true do %> <i class="fa fa-heart-o" aria-hidden="true"></i> <%= book.favorites.count %> <% end %> <% end %>非同期機能の実装
1. jQueryの導入
Gemfilegem 'jquery-rails'ターミナル$ bundleapplication.js//= require rails-ujs //= require activestorage //= require turbolinks //= require jquery //= require_tree .2. いいね後のジャンプ先を削除
favorites.controll.rbclass FavoritesController < ApplicationController def create @book = Book.find(params[:book_id]) unless current_user.favorited_by?(@book) favorite = current_user.favorites.new(book_id: @book.id) favorite.save end end def destroy @book = Book.find(params[:book_id]) favorite = current_user.favorites.find_by(book_id: @book.id) favorite.destroy end end3. パーシャルの親要素にクラスをつける
books/_books.html.erb#eachで呼び出されている各投稿のいいねボタンに対して、それぞれ一意のクラスを付けている <td class="favoritebutton_<%= book.id %>"> <%= render 'favoritebutton', book: book %> </td>4. JavaScriptファイルの作成
favorites/create.js.erb$(".favoritebutton_<%= @book.id %>").html("<%= j(render 'books/favoritebutton', book: @book ) %>");favorites/destroy.js.erb$(".favoritebutton_<%= @book.id %>").html("<%= j(render 'books/favoritebutton', book: @book ) %>");
$(".favoritebutton_<%= @book.id %>")
➡︎「3」で付けたクラスを指定
.html("<%= j(render 'books/favoritebutton', book: @book ) %>");
➡︎いいねボタンのパーシャルをrenderしている参考サイト
- 投稿日:2020-04-04T12:52:37+09:00
エラー「...mysql2/client.rb:90: [BUG] Segmentation fault at 0x00000000000000」に苦しんだ
エラー「...mysql2/client.rb:90: [BUG] Segmentation fault at 0x00000000000000」
で非常に苦しみました。
改善したので、メモしておきます。Rails sはできるが、どこかページを読み込もうとしようと、エラーが発生します。
改善の参考になった記事は、下記になります
エラー「...mysql2/client.rb:90: [BUG] Segmentation fault at 0x00000000000000」(セグフォ/セグメンテーション違反)に対応した
これでmysqlをアンインストールします。mysqlの再インストール方法は、自分の環境構築方法である
VS codeの初期設定とRuby on Railsの環境設定のMysqlの構築をしました。しかし、
エラー「Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib (LoadError)」が表示されましたこの対応方法は下記のサイトが有効でした
https://note.com/shoki_rails/n/nf7b51ba48084$ bundle exec gem uninstall mysql2 > 3ですべてのバージョンを削除する $ bundle install $ rails s >改善
- 投稿日:2020-04-04T11:03:41+09:00
【Rails 】部分テンプレート使用時のディレクトリ命名方法について/partialディレクトリとsharedディレクトリの使い分け
★気になっていたこと
RailsではDRYの原則が定められていることから、頻繁に使用する「部分テンプレート」。使用していく中で、「partial」「shared」と
似たような意味合いを持つ単語が出てきて混乱していました。★結論
大変ざっくりとしていますが、「partial」「shared」の使い分けは以下のようです。①「shared」を使用する状況としてはdeviceのgemを使用しているタイミング。
device入れたときは自動でsharedディレクトリが生成されるので、
その中に使用するファイルを格納する。
②device外で使用するファイルについては、現場によってディレクトリ名は異なる。
「partial」と絶対命名するわけではない。細かい部分ですが、少し気になったので備忘録として残します。
- 投稿日:2020-04-04T06:25:33+09:00
Rails-APIでsorceryを使ったらundefined local variable or method `form_authenticity_token'と怒られた
概要
Rails-APIにて認証用のgem sorceryを使ってloginメソッドを叩いた時に
undefined local variable or method `form_authenticity_token'と怒られたので解決策を書きます。
環境
ruby 2.6.5
Rails 6.0.2.1
sorcery (0.14.0)結論
ログイン処理を行うコントローラーに下記を追加すればOK
sessions_controller.rbprivate def form_authenticity_token; end原因
こちらの記事によると、ユーザーがログインする際にCSRFトークンがリセットされるのですが、それを行うform_authenticity_tokenメソッドがRails-APIに存在しないかららしいです。
このメソッドがないと動作が保証されないので、とりあえず自前で空メソッドを用意してくれ、とのことでした。
見た目はブサイクになりますが仕方なくこれで対応して無事に動きました。
- 投稿日:2020-04-04T00:12:11+09:00
【Rails】migrationファイルまとめ(カラム追加・削除・変更)
はじめに
学習中の備忘録です。
概要
- カラムのデータ型一覧
- モデル作成時
- カラム追加
- カラム削除
- データ型変更
- カラム名変更
- モデル作成時(外部キー制約付)
- カラム追加時(外部キー制約付)
カラムデータ型一覧
データ型 型の種類 用途 integer 数字 金額、回数など string 文字(短文) ユーザー名、メールアドレスなど text 文字(長文) 投稿文など boolean 真偽 はい・いいえの選択肢など datetime 日付と時刻 作成日時、更新日時など float 浮動小数 小数点含む6桁までを丸めずに保存 decimal 精度の高い少数 小数点以下桁数揃えて正確に保存 timestamp より細かい日時 より細かい日時 time 時間 時間 date 日付 日付 binary バイナリデータ バイナリデータ ※floatとdecimalについて詳しくはこちら
https://qiita.com/y-ken/items/b8601092d0261c3a556d
※datetime,time,dateについて詳しくはこちら
https://qiita.com/y-ken/items/b8601092d0261c3a556d前提
- rails 5.2.4.1
- コマンド入力はファイル名のみですのでファイルは編集してください。
モデル作成時
postモデルを作成。
rails g model postmigrationファイルを編集してpostsテーブルにpostカラムをstring型で作成。
class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.string :post t.timestamps end end endカラム追加
migrationファイル作成。
rails g migration AddTitleToPostspostsテーブルにtitleカラムをstring型で追加。
class AddTitleToPosts < ActiveRecord::Migration[5.2] def change add_column :posts, :title, :string end endカラム削除
migrationファイル作成。
rails g migration RemoveTitleFromPostspostsテーブルのtitleカラムを削除。
class RemoveTitleFromPosts < ActiveRecord::Migration[5.2] def change remove_column :posts, :title, :string end endデータ型変更
migrationファイル作成。
rails g migration ChangeDatatypeNameOfPostspostsテーブルのnameカラムをtext型に変更。
class ChangeDatatypeNameOfPosts < ActiveRecord::Migration[5.2] def change change_column :posts, :name, :text end endカラム名変更
migrationファイルを作成。
rails g migration RenameNameColumnToPostspostsテーブルのnameカラムのカラム名をtitleに変更。
class RenameNameColumnToPosts < ActiveRecord::Migration[5.2] def change rename_column :posts, :name, :title end endモデル作成時(外部キー制約付)
postsテーブルにuser_idという外部キー付のカラムを作成。
class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| #~省略~ # user_idという名前で users.id への外部キー制約をはる t.references :user, foreign_key: true t.timestamps end end endカラム追加時(外部キー制約付)
postsテーブルにuser_idという外部キー付のカラムを作成。
class AddUserIdToPosts < ActiveRecord::Migration[5.2] def change #user_idという名前で users.id への外部キー制約をはる add_reference :posts, :user, foreign_key: true end end※foreign_key オプションを省略してしまうと、外部キー制約がはられません。
※indexを作りたくない場合はオプションで明示的に index: false を記述。まとめ
今回は個人的に日頃使用するものでまとめました。
コマンド入力や外部キーについては参考記事にもっと詳しく書いてあります。参考記事
https://qiita.com/dawn_628/items/13fa64dc6d600e921ce3
https://qiita.com/publichtml/items/1fba15d8071fab66d043