- 投稿日:2020-10-21T23:18:43+09:00
ユーザー認証の導入
ユーザー認証の導入
Basic認証
HTTP通信の規格に備え付けられている、ユーザー認証の仕組みのこと
RailsアプリケーションにBasic認証を導入
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :basic_auth (省略) private def basic_auth authenticate_or_request_with_http_basic do |username, password| username == 'admin' && password == '1111' end end end開発環境の環境変数に、ユーザー名とパスワードを設定
macOSがCatalina以降
ターミナル% vim ~/.zshrc # .zshrcを開いたら、「i」とタイプしてインサートモードに移行 # .zshrcの内部に次の記述を追加 export BASIC_AUTH_USER='admin' export BASIC_AUTH_PASSWORD='2222' # 記述を追加したら、escキーを押してインサートモードを抜け、 「:wq」と入力して保存して終了する # .zshrcを再読み込みし、定義した環境変数を有効にする % source ~/.zshrcmacOSがMojave以前の方
ターミナル$ vim ~/.bash_profile # .bash_profileを開いたら、「i」とタイプしてインサートモードに移行 # .bash_profileの内部に次の記述を追加 export BASIC_AUTH_USER='admin' export BASIC_AUTH_PASSWORD='2222' # 記述を追加したら、escキーを押してインサートモードを抜け、 「:wq」と入力して保存して終了する # .bash_profileを再読み込みし、定義した環境変数を有効にする $ source ~/.bash_profile
- 投稿日:2020-10-21T21:36:01+09:00
rails DB作成から追加、保存、削除
はじめに
rails consoleでDBの作成、内容の追加、保存、削除まで。
Userテーブルの作成
$ rails g model User name:string email:string
id name(string) email(string) 1 alice alice@gmail.com 2 tom tom@gmail.com データベースに変更を反映
$ rails db:migrateデータの追加(C)
$ rails console > user = User.new(name:"alice", email:"alice@gmail.com") > user.saveデータの読み取り(R)
> user = User.all > user[0]データの更新(U)
> user = User.all > user0 = user[0] > user[0].name = "alice_alice" > user[0].saveデータの削除(D)
> user[0].destroyバリデーション
オブジェクトがDBに保存される前に、そのデータが正しいかどうかを検証する仕組みをバリデーションという
「emailの重複がないか」をチェックするためのバリデーション
class User < ApplicationRecord validates :email, {uniqueness: true} end文字数をチェックするバリデーション
class Post < ApplicationRecord validates :content, {presence: true, length: {maximum: 140}} end
- 投稿日:2020-10-21T21:36:01+09:00
rails DB作成から追加、保存、削除、カラムの追加
はじめに
rails consoleでDBの作成、内容の追加、保存、削除まで。
Userテーブルの作成
$ rails g model User name:string email:string
id name(string) email(string) 1 alice alice@gmail.com 2 tom tom@gmail.com データベースに変更を反映
$ rails db:migrateデータの追加(C)
$ rails console > user = User.new(name:"alice", email:"alice@gmail.com") > user.saveデータの読み取り(R)
> user = User.all > user[0]データの更新(U)
> user = User.all > user0 = user[0] > user[0].name = "alice_alice" > user[0].saveデータの削除(D)
> user[0].destroyバリデーション
オブジェクトがDBに保存される前に、そのデータが正しいかどうかを検証する仕組みをバリデーションという
「emailの重複がないか」をチェックするためのバリデーション
class User < ApplicationRecord validates :email, {uniqueness: true} end文字数をチェックするバリデーション
class Post < ApplicationRecord validates :content, {presence: true, length: {maximum: 140}} endカラムの追加
id name(string) email(string) 1 alice alice@gmail.com 2 tom tom@gmail.com これにユーザーの画像の情報を追加する!
$ rails g migration add_image_name_to_usersマイグレーションフォルダ
/db/migration/
にファイルが追加される。マイグレーションファイルの見方
/db/migration/20201010_create_post.rb
の中身
rails g model
で作ったマイグレーションファイルには、changeメソッドは自動生成されていた。
なので、特に変更することなく、rails db:migrate
で変更を反映できていた。class CreateUsers < ActiveRecord::Migration[5.0] def change create_table :users do |t| #postsという名前のテーブルを作成 t.string :name #データ方がstringであるnameという名前のカラムを作成 t.string :email #データ方がstringであるemailという名前のカラムを作成 t.timestamps end end endカラムの追加は自分でしないといけない
今回、カラムを追加するので、自分でchangeメソッドの中身を書く必要がある。
class AddImageNameToUsers < ActiveRecord::Migration[5.0] def change add_column uses, image_name, string #テーブル名、カラム名、データ型 end endchangeメソッドの中身を実行する
$ rails db:migrate
- 投稿日:2020-10-21T21:36:01+09:00
rails DB作成から追加、保存、削除、カラムの追加、画像の保存
はじめに
rails consoleでDBの作成、内容の追加、保存、削除まで。
Userテーブルの作成
$ rails g model User name:string email:string
id name(string) email(string) 1 alice alice@gmail.com 2 tom tom@gmail.com データベースに変更を反映
$ rails db:migrateデータの追加(C)
$ rails console > user = User.new(name:"alice", email:"alice@gmail.com") > user.saveデータの読み取り(R)
> user = User.all > user[0]データの更新(U)
> user = User.all > user0 = user[0] > user[0].name = "alice_alice" > user[0].saveデータの削除(D)
> user[0].destroyバリデーション
オブジェクトがDBに保存される前に、そのデータが正しいかどうかを検証する仕組みをバリデーションという
「emailの重複がないか」をチェックするためのバリデーション
class User < ApplicationRecord validates :email, {uniqueness: true} end文字数をチェックするバリデーション
class Post < ApplicationRecord validates :content, {presence: true, length: {maximum: 140}} endカラムの追加
id name(string) email(string) 1 alice alice@gmail.com 2 tom tom@gmail.com これにユーザーの画像の情報を追加する!
$ rails g migration add_image_name_to_usersマイグレーションフォルダ
/db/migration/
にファイルが追加される。マイグレーションファイルの見方
/db/migration/20201010_create_post.rb
の中身
rails g model
で作ったマイグレーションファイルには、changeメソッドは自動生成されていた。
なので、特に変更することなく、rails db:migrate
で変更を反映できていた。class CreateUsers < ActiveRecord::Migration[5.0] def change create_table :users do |t| #postsという名前のテーブルを作成 t.string :name #データ方がstringであるnameという名前のカラムを作成 t.string :email #データ方がstringであるemailという名前のカラムを作成 t.timestamps end end endカラムの追加は自分でしないといけない
今回、カラムを追加するので、自分でchangeメソッドの中身を書く必要がある。
class AddImageNameToUsers < ActiveRecord::Migration[5.0] def change add_column uses, image_name, string #テーブル名、カラム名、データ型 end endchangeメソッドの中身を実行する
$ rails db:migrate画像の保存
ファイルの書き込み
File.write
を使う。$ rails console > File.write("public/aaa.txt", "Hello World") # File.write(書き込む場所, 内容)画像データの書き込み
File.binwrite
とread
メソッドを使う。
public/user_images/"1.jpg"
に 読み込んだimage
を書き込んで保存する。if image = params[:image] @user.image_name = "#{@user.id}.jpg" File.binwrite("public/user_images/#{@user.image_name}", image.read) end
- 投稿日:2020-10-21T20:41:06+09:00
続・データベースになくても、データとして扱える活動的なハッシュ 〜表示編
はじめに
ActiveHashの使い方については以前投稿した、こちらを参考にしてください。
ActiveHashの文字列を取り出す方法
ActiveHashに入れて保存されているデータを、ビューに表示させたいときは、カラム名だけでは、数値が表示されるだけなので、
ex)item.prefecture.nameとカラム名の後に
name
とつけると、idに紐づいた文字列が表示されるようになる。
- 投稿日:2020-10-21T19:52:23+09:00
RailsのJSONレスポンスの表示形式についてまとめました
JOSNレスポンスの表示形式についてよくわかってなくて
はまったので整理しました。ActiveModelSerializerには、アダプター(JSONの表示形式)を3種類ある。
- :attributes (default)
- :json
- :json_api
attributes:デフォルトで設定されているアダプタ。ルートキーなしでjsonレスポンスを生成する。
json:レスポンスは常にルートキーありでjsonレスポンスを生成する
json_api:JSONAPIという、JSONの仕様を決めている組織が制定している表示形式に沿ったレスポンスが返ってくる:jsonと:json_apiをデフォルトで使いたい場合には、initializersディレクトリに
別途active_model_serializers.rbというような(名前はなんでもOK)ファイルを作成し、
そこに以下のようにJSONの表示形式を設定する。# config/initializers/active_model_serializers.rb ActiveModel::Serializer.config.adapter = :json_api実際のレスポンスは以下の感じになります
- attributes
[ {"id"=>69, "title"=>"鍋", "updated_at"=>"2020-10-20T20:52:09.044Z", "user"=> {"id"=>3, "name"=>"xu6i65h83tbvexx5dld89w39xn4u9", "email"=>"3_ahmad@smith-brekke.biz"} } ]
- json
"articles"がルートキーになります。
ルートキー名はcontroller名を取得しています。{"articles"=> [ {"id"=>72, "title"=>"あらそう", "updated_at"=>"2020-10-20T20:58:15.458Z", "user"=> {"id"=>3, "name"=>"e8zu6a5m08jlgd3w1ddlxkoa", "email"=>"3_ernest_denesik@deckow-gutkowski.com"} }, ] }
- json_api
{"data"=> [ {"id"=>"66", "type"=>"articles", "attributes"=>{"title"=>"ひんきゃく", "updated-at"=>"2020-10-20T20:44:16.765Z"}, "relationships"=> {"user"=> {"data"=> {"id"=>"3", "type"=>"users"} } } } ] }だんだん構造化されていってる感じですね。
json_apiがJSONの仕様に沿った表示形式ということは
一番汎用化しやすいってことですかね。
- 投稿日:2020-10-21T19:33:10+09:00
Ruby on Rails メールの自動送信機能 実装
内容
登録されたメールアドレスに、確認メールを自動送信する機能を実装する。
実装
①アプリ作成
sampleというアプリを作ります。
$ rails new sampleディレクトリを移動。
$ cd sample新規に追加されたメールアドレスに送るアプリを作りますので、Userテーブルを作成します。
今回はカラムを2つにします。$ rails g scaffold User name emailデータベースを作成します。
$ rails db:migrate②メール送信設定
Gmailを送れるように設定をしていきます。
①config/environments/development.rb
②config/environments/production.rb
①、②に下記のを追加してください。Rails.application.configure do config.action_mailer.raise_delivery_errors = true #falseからtrueに変更 #中略# config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', domain: 'smtp.gmail.com', port: 587, user_name: Rails.application.credentials.gmail[:user_name], password: Rails.application.credentials.gmail[:password], authentication: 'login', enable_starttls_auto: true } end③メーラー作成
メール送信におけるコントローラー的役割を果たすものです。
メーラーの名前はSampleMailerとします。
$ rails g mailer SampleMailer実行すると、app/mailers以下に次の2つのメーラーが作成されます。
①application_mailer 「全体のメーラーの設定」
②sample_mailer 「先ほど作成したSampleMailerという個別のメーラーの設定」③メーラーの編集
①application_mailer 「全体のメーラーの設定」
app/mailers/application_mailer.rbclass ApplicationMailer < ActionMailer::Base default from: "Yamada Taro", #差出人の名前 reply_to: Rails.application.credentials.gmail[:user_name] #差出人のメールアドレス layout 'mailer' end②sample_mailer 「個別のメーラーの設定」
app/mailers/sample_mailer.rbclass PostMailer < ApplicationMailer default from: "Yamada Taro" def published_email(user) @user = user mail to: user.email #新規登録されたメールアドレス end end④メールの本文作成
メールの本文はapp/views/sample_mailerの配下に作ります。
メールの本文は、「HTMLバージョン」、「テキストバージョン」の2タイプがあります。今回は、これを作成します。
①published_email.html.erb 「HTMLバージョン」
②published_email.tex.erb 「テキストバージョン」app/views/sample_mailer/published_email.html.erb<!doctype html> <html lang="ja"> <head> <meta content="text/html; charset=UTF-8" /> </head> <body> <h2><%= @user.name %> 様</h2> <hr /> <p> こんにちは! <%= @user.name %>さん!</p> <hr /> </body> </html>app/views/sample_mailer/published_email.text.erb=============================== <%= @user.name %>様 =============================== こんにちは! <%= @user.name %>さん⑥コントローラーの編集
コントローラーの「createメゾット」に一行追加してください。
app/controllers/users_controller.rbclass UsersController < ApplicationController #中略 def create @user = User.new(user_params) respond_to do |format| if @user.save SampleMailer.published_email(@user).deliver #こちらを追加する。 format.html { redirect_to @user, notice: 'User was successfully created.' } format.json { render :show, status: :created, location: @user } else format.html { render :new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end #中略 end⑥ルーティングの編集
最後にルーティングの設定したら完了です。
config/routes.rbRails.application.routes.draw do resources :users root "users#index" #こちらを追加する。 end最後に起動させて確認して見ましょう!
$ rails sこのように画面が出てきます!
実際に操作して確認して見て下さい。以上実装は終了です。
ご視聴頂きありがとうございました。
- 投稿日:2020-10-21T18:38:24+09:00
Ruby on RailsでRSS/Atom形式のサイトマップをつくった
自社サイトのSEO対策でRSSフィード作成を担当したのでその方法をメモしておきます。
なんでSEO対策にRSSなのか?
その前にサイトマップについておさらい。
サイトマップとは「クローラーにページを見つけてもらいやすくするためにサーバーに置くファイル」
サイトマップには以下の種類がある。XMLサイトマップ
- クロール・インデックスさせたいURLをすべて記述する。
- その分サイズが大きい。
- そのためクローラーがあんまり見に来てくれないらしい。ぴえん
RSS/Atomフィード
- 最近の変更のみ記述する。
- そのためサイズが小さい。
- だからXMLサイトマップよりもクローラーが見に来てくれる頻度が高い。
私が開発を担当しているサイトは、イベント情報を載せて集客をするサイトなので、
1日に新規ページが何ページも増える
→新しい増えたページをできるだけ早くクロールしてもらいたい
→サイトマップだけではなく、RSS/Atomフィードを設置することにした。RSSフィード作成
標準ライブラリ
RailsにはRSSを扱うための標準ライブラリ(https://docs.ruby-lang.org/ja/latest/library/rss.html) が用意されていてrequireするだけで使える。
require 'rss'フィード作成処理
あとはRSSフィードを作りたいところで
## # [param] event_list : フィードに載せるエントリのリスト # def create_rss_feed(event_list) # 今回はAtom1.0フォーマットで作成 feed = RSS::Maker.make('atom') do |maker| maker.channel.about = 'tag:sample.com:feed' # フィードを一意に示すID。多分一意ならなんでもいい。 maker.channel.title = "新着イベント" # フィードのタイトル maker.channel.description = "イベントの最新情報をご紹介します。" # フィードの説明文 maker.channel.link = 'https://sample.com/' # サイトURL maker.channel.author = 'イベント事務局' # フィードの作成者 maker.channel.date = .strftime('%Y-%m-%d %H:%M:%S') # フィードの最終更新日時 event_list.each_with_index do |event| maker.items.new_item do |item| item.link = event.url # 詳細ページのURL item.title = event.title # 詳細ページのタイトル item.date = event.start_time.strftime('%Y-%m-%d %H:%M:%S') # イベントなら開催日、記事なら公開日など end end end render xml: feed.to_xml endこのような処理を書いて実行すると
このようにブラウザ上でRSSフィードが表示されました!
今回はAtomというフォーマットで作成しましたが、違うフォーマットで作成するときは
RSS::Maker.make('atom')
この「atom」の箇所を例えばRSS2.0であれば「2.0」に変えればよいそう。おわりに
標準ライブラリが用意されていたのであっという間にできてしまいました。
Railsってすごい〜〜と思うことばかりです。
- 投稿日:2020-10-21T17:56:57+09:00
簡単なリコメンデーション機能を作りました。
リコメンデーション機能気になる理由
→ オススメが最近使われています
→ 面白いので、調べたい
関連する記事
- https://medium.com/@ysmiracle/build-a-recommendation-engine-in-ruby-f6c4b44f2916
- https://dev.to/matiascarpintini/building-a-rails-recommendation-engine-216o
まずに映画のオススメを作ります
- ユーザーに面白いそう映画をオススメする機能
アルゴリズム(1)
アルゴリズム(2)
アルゴリズム(3)- スコアリング
- 関係性が高い → 点数が高い
- 点数が高い → オススメが多い
Railsでスコアリングを書きました。
def recommend_movies # recommend movies to a user # find all other users, equivalent to .where(‘id != ?’, self.id) other_users = self.class.all.where.not(id: self.id) # instantiate a new hash, set default value for any keys to 0 recommended = Hash.new(0) # for each user of all other users other_users.each do |user| # find the movies this user and another user both liked common_movies = user.movies & self.movies # calculate the weight (recommendation rating) weight = common_movies.size.to_f / user.movies.size # add the extra movies the other user liked common_movie_ids = common_movies.pluck(:id) user.movies.each do |movie| next if common_movie_ids.include? movie.id # put the movie along with the cumulative weight into hash recommended[movie] += weight end end # sort by weight in descending order sorted_recommended = recommended.sort_by { |key, value| value }.reverse end
Railsで表示する
https://github.com/phamthanhthuongbk/recommendation-rails
まずに友達のオススメを作ります。
- 映画のアルゴリズムと同じ作ります。
結果は
https://github.com/phamthanhthuongbk/recommendation-rails
感想
- アルゴリズムが分かりやすい、効果が見えました。
- オススメの動きがイメージが出来ました。
- スコアリングのため、全部のDBを見ないといけないので、大きなシステムだとどうかな
- 投稿日:2020-10-21T17:55:14+09:00
RailsにBootstrapを導入!!
RailsにBootstrapを導入する方法を説明致します。
手順は、とても簡単ですのでご参考にどうぞ!!
手順は、4つあります。手順
1.Bootstrapのインストール
2.SCSSファイルの作成
3.JSファイルの修正
4.Rails(Puma)の再起動1.Bootstrapをgemでインストール
RailsでBootstrapを使う場合は、gemを使ってインストールする方法が一般的です。
Bootstrapは内部でjQueryを利用しているので、こちらもあわせてインストールしましょう。
Gemfileに以下を追記して、bundle installを実行してみてください。Gemfilegem 'bootstrap', '~> 4.3.1' gem 'jquery-rails'ターミナル% bundle install2. SCSSファイルを作成
次に、application.cssをapplication.scssというファイル名に変更します。
これは、Bootstrapが「SCSS」という記法で書かれており、Railsでもあわせて利用するためです。
「SCSS」とは、CSSを拡張した記法のことで、いまのWeb業界では多く利用されている記法になります。
ここでは具体的な解説はしませんが、CSSの記述よりも見やすく、書きやすくなった記法だと思ってください。ファイルの拡張子を変更変更前 app/assets/stylesheets/application.css 変更後 app/assets/stylesheets/application.scssファイル名を変更したら、実際にファイルを開いて下さい。
*= require_tree .と*= require_selfを削除し、
@import "bootstrap";を追記します。
追記したコードが、Bootstrapを読み込むための設定になります。app/assets/stylesheets/application.scss/* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's * vendor/assets/stylesheets directory can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the bottom of the * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS * files in this directory. Styles in this file should be added after the last require_* statement. * It is generally better to create a new file per style scope. * *= require_tree . <(削除) *= require_self <(削除) */ @import "bootstrap"; <(追加)3. JSファイルを修正
Bootstrapで使われる「JavaScript」や「jQuery」などの関連ファイルを読み込む設定をします。
app/assets/javascripts/application.jsを開き、以下を参考に元々あったコードの上に追記してください。app/assets/javascripts/application.js# 以下の3つを追記 //= require jquery3 //= require popper //= require bootstrap # 元々あったコード //= require rails-ujs //= require activestorage //= require turbolinks4. Rails(Puma)を再起動
ここで一度、ブラウザからアクセスしてみてください。
もし、この段階でエラーが表示されているのであれば、Rails(Puma)を再起動します。
それでもエラーが変わらない場合は、「node.js」のバージョンが古い可能性があります。
DockerでRailsを構築した方は、Dockerfileが以下のような設定になっているかを確認してください。Dockerfile# Railsに必要なパッケージをインストール RUN apt-get update -qq && apt-get install -y nodejs RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \ && apt-get install -y nodejs # 以下の公式サイトの記述では、node.jsのバージョンが低くてbootstrapが使えない # RUN apt-get update -qq && apt-get install -y nodejsまとめ
導入手順は難しいと思うかもしれませんが、この説明した手順の通りに記述を削除したり、
書き換えたりするだけですので意外と簡単です。
是非試してみて下さい!!以上。
- 投稿日:2020-10-21T17:41:53+09:00
【結合テストコード】date_selectから要素を選択する方法
簡単な結合テストコードを書いていてドツボにハマったので備忘録的に残しておきます。間違っていたらご指摘頂けると幸いです。
<%= raw sprintf( form.date_select( :birthday, class:'select-birth', id:"birth-date", use_month_numbers: true, prompt:'--', start_year: 1930, end_year: (Time.now.year - 5), date_separator: '%s'), "<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>このような年、月、日を選択するフォームで思うように要素を選択できかったので悩んでいたのですが、以下の記事が参考になりました。
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」
結論としてはブラウザで検証を行い指定したい要素をチェックすると、きちんと1つずつname属性が割り当てられていたので、そのまま記述し
select '1930',from: 'dear_person[birthday(1i)]' select '12',from: 'dear_person[birthday(2i)]' select '12',from: 'dear_person[birthday(3i)]'こちらで無事パスしました。
完全に私のミスです。
- 投稿日:2020-10-21T16:50:06+09:00
フォーム項目の入力有無による条件分岐
環境
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
前提
下記の条件分岐を行うことがゴールです。
入力必須ではない項目が入力された時→詳細画面で表示(図1)
一方、入力されなかった時→詳細画面で表示されない(図2)結論 .present?を使用
if文の条件式の際に、
.present?
を使用することで、条件分岐することが出来ます。
そのため、@report.otherの値が存在する際には、備考の内容が表示されます。show.html.erb<% if @report.other.present? %> <tr> <th class="detail-name">備考</th> <td class="detail-value"><%= @report.other %></td> </tr> <% end %>以上です。
最後までお読みいただきありがとうございます!
同じことで悩んでいる方の手助けになったら幸いです!参考
下記のサイトを参考にして、私自身も解決出来ました。
オブジェクトの記法についてより知りたい方は、下記ご確認ください!
- 投稿日:2020-10-21T16:50:06+09:00
入力必須ではない項目の入力有無による画面の表示方法
環境
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
概要
下記の条件分岐を行うことがゴールです。
入力必須ではない項目が入力された時→詳細画面で表示(図1)
一方、入力されなかった時→詳細画面で表示されない(図2)結論 .present?を使用
if文の条件式の際に、
.present?
を使用することで、条件分岐することが出来ます。
そのため、@report.otherの値が存在する際には、備考の内容が表示されます。show.html.erb<% if @report.other.present? %> <tr> <th class="detail-name">備考</th> <td class="detail-value"><%= @report.other %></td> </tr> <% end %>以上です。
最後までお読みいただきありがとうございます!
同じことで悩んでいる方の手助けになったら幸いです!参考
下記のサイトを参考にして、私自身も解決出来ました。
オブジェクトの記法についてより知りたい方は、下記ご確認ください!
- 投稿日:2020-10-21T16:40:45+09:00
PayjpのCustomer作成とdefault_cardの設定
はじめに
Payjpの決済方法の記事はたくさんありますが、default_card設定方法はなかったので書かせていただきます。
トークン化については他の方が書かれているので、javascriptの記述は割愛します。開発環境
ruby 2.6.5
Rails 6.0.3.3参考
説明不足なところはこちらで補ってください。
リファレンス:
https://pay.jp/docs/api/#customer-%E9%A1%A7%E5%AE%A2
https://pay.jp/docs/customerCardモデル
自分の場合はCardモデルで下記のカラムを保存しています。
id user_id card_token customer_token integer tok_~ cus_~ Customer作成
Customer作成にはcard_token(tok_~)が必要になります。
javascriptで受け取ったtokenをコントローラーに渡して、下記の記述をします。cards_controller.rbdef create # card_tokenが正しいか確認 if params[:card_token] == nil redirect_to new_user_card_path return end # ユーザーのcustomer_tokenが存在する場合 if Card.find_by(user_id: current_user.id) card = current_user.card customer = Payjp::Customer.retrieve(card[0][:customer_token]) customer.cards.create( card: params[:card_token] ) else # ユーザーがcustomer_tokenが存在していない場合 customer = Payjp::Customer.create( description: "test", card: params[:card_token],) end # cardテーブルに保存 card = Card.new( user_id: current_user.id, card_token: params[:card_token], customer_token: customer.id) endCustomer情報取得
配列
@cards
を定義して、customer_tokenをもとにcard情報を入れますcard.controller.rbcards = Card.where(user_id: current_user.id) @cards = [] cards.each do |card| @customer = Payjp::Customer.retrieve(card.customer_token) @cards << @customer.cards endユーザーにカードを選択してもらい、引数「i」で選択されたindexを受け取れるようにフォームを作成します。
ビューで@cards
に対してeach_with_indexで下記の記述でカード情報を表示させられます。select.html.erb<%= form_with url: set_default_card_path, method: :post, local: true do |f| %> <% @cards.each_with_index do |card, i| %> <%=f.radio_button :selected, :"#{i}" ,id: "check_card", checked: (card.data[i] [:id] == @customer[:default_card]) %> <%= "**** **** **** #{ + card.data[i][:last4]}" %> <%= "#{card.data[i][:exp_year]}年#{+ card.data[i][:exp_month]}月" %> <% end %> <%= f.submit "次へ進む" %> <% end %>default_cardの設定方法
select.html.erbのform_withの中でradio_buttonを使い、params[:selected]に#{i}の値を受け取っています。
@customer
の[:default_card]に代入して、@customer.saveで完了します。
※@customer.saveをしないと更新されません。cards_controllerdef set_default_card cards = Card.where(user_id: current_user.id) @cards = [] cards.each do |card| @customer = Payjp::Customer.retrieve(card.customer_token) @cards << @customer.cards end @customer = Payjp::Customer.retrieve(card.customer_token) index = params[:selected].to_i @customer[:default_card] = @cards[0].data[index][:id] @customer.save end念のため
- customerを作成していない場合、card_token(tok_~)があれば、Payjp::Charge.createができます。
- customerを作成した場合、cardのid(car_~)、もしくはcustomerのid(cus_~)があればPayjp::Charge.createができます。
- customerのidを渡した場合はcustomerのdefault_cardが使われます。 (指定しない場合は最後に登録したカードがdefault_cardになります。)
最後に
もっと簡便な記述もあるかも知れませんが、これで実装することはできます。
あとは、各々アレンジしてください。
- 投稿日:2020-10-21T16:17:16+09:00
確認画面を経由すると画像データがnilになる時の解決方法
投稿画面→確認画面→投稿完了の流れで作成したい時ってありませんか?
確認画面加えるだけなんですが、データの保存や扱いが少し違っていたことで詰まりました。。
その時の経験を備忘録として書いていきます!この記事が参考になるであろう方
・確認画面では画像が表示されるのに、投稿詳細画面では画像がアップロードできていない。
・binding.pry
等でデバッグして投稿確認のアクション(confirmアクション)の挙動を確認すると、imageだけnilになっている。
・SQL操作をして確認してみても、やはり画像データだけが保存されてない。なぜnilになるのか?
どうやら、確認画面を経由した場合には、確認画面から戻される情報に画像データは無いみたいです。
確認画面を表示する前に画像データを別で保存しておき、それを取り出して使う必要があるようです。
解決方法の結論
・ 確認画面内に
hidden
の記述を加える。
・:image_cache
のパラメータを使用する。
(コントローラ内で:image_cache
を渡すのを忘れないように。。)hidden= 隠しデータをサーバーに送信する際に使用。value属性で指定した値がサーバーへ送信する。
image_cache= 画像のデータそのものを取り扱うパラメータ。(確認画面の実装を挟む際等に使用するパラメータです。)
参考コード
new.html.erb<div class="thumbnail"> <%= f.file_field :image %> <%= f.hidden_field :image_cache %> ← 追記 </div> <%= f.submit "確認画面へ" %>confirm.html.erb<%= form_with model: @tournament, url: tournaments_path, html: { method: :post }, local: true do |f| %> <%= f.hidden_field :start_time %> <%= f.hidden_field :image %> <%= f.hidden_field :image_cache %> ← 追記 <%= f.submit "作成する"%> <% end %>tournaments_controller.rbdef tournament_params params.require(:tournament).permit(:start_time, :image, :image_cache) endこれで画像データが受け取れて表示できる!..はずです。
最後に
確認画面を経由した場合の記述は所々変わってきてくるので、意外に詰まってしまいますね。もっとたくさんの経験して成長したいと思います!!
同じ境遇になった方のお役に立てば嬉しいです。
解決や参考になったらLGTMして頂けると喜びます。笑
- 投稿日:2020-10-21T14:49:21+09:00
【Rails】deviseの「新規登録」「ログイン」「情報更新」機能をカスタマイズする際に必要なストロングパラメーターのsanitizerメソッド
はじめに
deviseの「新規登録」「ログイン」「情報更新」機能をカスタマイズする際に必要なストロングパラメーターのsanitizerメソッド
と長いタイトルになってしまいましたが、要は「deviseのユーザー管理機能」についてです。
deviseを使うとユーザー管理機能が簡単に作れますが、デフォルトの機能を変更するには様々な設定が必要です。
今回は「新規登録」「ログイン」「情報更新」をカスタマイズする際に必要な処理について紹介します。目次
1.結論
2.devise_parameter_sanitizerメソッドについて
3.sanitizerメソッドの構文
4.処理毎の記述
5.記述するファイル
6.まとめ対象の方
deviseを使った事がある
deviseのデフォルト以外の実装がしたい
ストロングパラメーターを理解してる開発環境
ruby 2.6.5
rails 6.0.0
devise 4.7.31.結論
まず結論は以下のような記述になります。
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base #もしdeviseのコントローラーの事なら全てのアクションの前にメソッドを読み込む before_action :configure_permitted_parameters, if: :devise_controller? #ログイン機能について before_action :configure_account_update_parameters, if: :devise_controller? #編集機能について private #ログイン機能について def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :family_name_kanji, :first_name_kanji, :birthday]) end #編集機能について def configure_account_update_parameters devise_parameter_sanitizer.permit(:account_update, keys: [:nickname, :family_name_kanji, :first_name_kanji, :birthday]) end end※注意:「新規登録」と「情報更新」しか実装していないので、その2つについて記述します。
2.devise_parameter_sanitizerメソッドについて
まずメソッドの説明をします。
2.1 使用するタイミング
「新規登録」「ログイン」「情報更新」をデフォルト以外にカスタマイズしたい時です。
2.2 sanitizerメソッド
sanitizerメソッドとはdeviseのUserモデルに関わるパラメーターを取得するメソッドです。
deviceの内部にデフォルトでパラメーターを取得する記述がされてますが、これに消毒剤=(sanitizer)をかけてカスタマイズできる状態にすることです。
※注意:個人的な解釈の仕方です。次に、sanitizerメソッドとpermitメソッドを組み合わせます。
そうする事で、deviseにデフォルトで定義されているストロングパラメーターに対して、自分で新しく追加したカラムも含めることができます。2.2 二種類あるpermitメソッドの違い
permitメソッドが二種類あるので、脱線しますが少し説明します。
「sanitizer」のpermitはdeviseのパラメーターを取得するためのメソッドです。
「Rails」のコントローラーで保存時などに使用してるparamsのpermitメソッドとは異なります。下記がそれぞれの例です。
controller.rb#例) paramsのpermitメソッド params.require(:モデル名).permit(:許可したいキー)app/controllers/application_controller.rb#例) devise_parameter_sanitizerのpermitメソッド devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可したいキー(カラム名)]3. sanitizerメソッドの構文
メソッド名はconfigure_permitted_parametersと慣習的に定義されてますが、自由に命名しても差し支えありません。
app/controllers/application_controller.rbprivate def configure_permitted_parameters # メソッド名は自由に命名しても差し支えありません。 # deviseのUserモデルにパラメーターを許可 devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可したいキー(カラム名)]) end※注意:プライベートメソッドの中で定義します。
以上devise_parameter_sanitizerメソッドの説明でした。
4.処理毎の記述
「2.1 使用するタイミング」 でも触れましたが処理する目的で「:devise処理名」の記述が変わります。
処理する目的は「新規登録」「ログイン」「情報更新」です。
処理名 目的 :sign_in ログイン(サインイン)の処理を行うとき :sign_up 新規登録(サインアップ)の処理を行うとき :account_update アカウント情報更新の処理を行うとき 5.記述するファイル
「どこに記述するか」ですが、これは「すべてのコントローラーが継承しているファイル」です。
つまり、application_controller.rbファイルです。
このコントローラーが読み込まれた後、他すべてのコントローラーが読み込まれます。
また、全てのアクションの処理前に処理したいのでbefore_actionを使います。app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? #↑これ# private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname]) #↑(:deviseの処理名, keys: [:許可したいキー(カラム名)]) end endこれでほとんどの実装ができました。あとはpermitも後を自分のしたい事に応じて編集するだけです。
上記は
deviseの処理名 = :sign_up
keys = [:nickname]
で実装してます。6.まとめ
手順のポイントは
application_controller.rbに記述
before_actionを設定
sanitizer.permitメソッドを使用以上、deviseの「新規登録」「ログイン」「情報更新」機能をカスタマイズする際に必要なストロングパラメーターのsanitizerメソッドについてでした。
最後に
私はプログラミング初学者ですが、同じ様に悩んでる方々の助けになればと思い、記事を投稿しております。
それでは、また次回お会いしましょう〜
- 投稿日:2020-10-21T14:09:52+09:00
【Rails6】Google Map をアプリに埋め込み、入力した住所にマーカーをつける。【細かいところの確認】
簡単に実装できるはずのGoogleMapAPIですが数々の沼にハマったので細かく注意していきます。
環境
Rails 6.0.0
Ruby 2.6.5
EC2
Amazon Linux2
Nginx
mariaDB
Capistrano機能
住所を入れると
DBに住所が保存、緯度経度が自動で算出されて
Google Mapをアプリに埋め込む
Google Map API(サービス紹介ページ)
Google Map APIは、GoogleCloudのサービスのひとつで、GoogleCloudPlatformというコンソールから操作します、まずはそこで、Google Map javascript APIのAPIKeyを取得します。
GoogleCloudPlatformへ
☆Googleのアカウントがなければまずこちらから登録してください。
Googleアカウント登録
アカウントを作成したら(持っていたら)コンソールへ
https://console.cloud.google.com/プロジェクトを作成し、APIKeyを取得→地図表示
https://qiita.com/nagaseToya/items/e49977efb686ed05eadb
一連の流れはこちらにわかりやすく書かれています。今回は、ここに加えて任意の住所記録、保存、出力します。
Geocording
緯度と経度を算出して、特定の位置を見つけてくれる機能です。gemのGeocoderと、Google CloudのGeocodeing APIというサービスを使います。
gemだけでも位置情報を取得することはできますが、「東京駅」では取得できても、「東京都〇〇区〇〇○○ー◯○」という具体的なアドレスでは取得できません。また取得できたりできなかったりします。そのためにより性能の良いGeocodeing APIも使えるようにします。コード
モデルは作成されているとします。(例Performancesモデル)
①マイグレーションファイルを作成(カラム追加)
% rails g migration AddColumnsToPerformances・入力された住所addressカラム
・geocodeによって自動で算出される緯度、経度カラムclass AddColumnsToPerformances < ActiveRecord::Migration[6.0] def change add_column :performances, :address, :string add_column :performances, :latitude, :float add_column :performances, :longitude, :float end end% rails db:migraterollbackでもカラムは変更できますが、データが消えるのでなるべくadd_column(カラム追加)にすると良いと思います!
②入力フォームの作成
保存先はaddressのみで大丈夫です。
<%= form_with(model: @performance, local: true) do |f| %> ***抜粋*** <label for="group-name">住所(GoogleMap表示)</label> <span class="indispensable-any">任意</span> <%= f.text_area :address,class:"new-performance-box", id:"gmap", placeholder:"Google Mapの住所をコピーして貼り付けてください" %> ***抜粋***③コントローラー
ストロングパラメーターでaddressを指定します。
performances_controller.erbbefore_action :set_performance, only: [:表示させるview] def create @performance = Performance.new(performance_params) if @performance.valid? @performance.save redirect_to "/users/#{current_user.id}" else render :new end end def 表示させるview @performance = Performance.new(performance_params) end private def set_performance @performance = Performance.find(params[:id]) end def performance_params params.require(:performance).permit(:address).merge(user_id: current_user.id) end④ビュー
CSSは別記してます。
zoomControl: false,
mapTypeControl: false,
fullscreenControl: false,
treetViewControl: false,
は拡大縮小ボタンなどを消す地図表示のオプションです。<div id='map'> <script> let map function initMap(){ map = new google.maps.Map(document.getElementById('map'), { center: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>}, zoom: 15, zoomControl: false, mapTypeControl: false, fullscreenControl: false, streetViewControl: false, }); marker = new google.maps.Marker({ position: {lat: <%= @performance.latitude %>, lng: <%= @performance.longitude %>}, map: map }); geocoder = new google.maps.Geocoder() } </script> <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['GOOGLE_MAP_API'] %>&callback=initMap" async defer></script> </div>※key=<%= ENV['GOOGLE_MAP_API'] %>の表記は充分気をつけてください!ここで=の位置が違うだけで全てうまくいきません・・・
⑤モデル
これでgeocordが緯度経度を算出してカラムに保存してくれます
performance.rbgeocoded_by :address after_validation :geocode, if: :address_changed?※if: :address_changed?がないと作用しないことがあるので気をつけてください!私はこれを書かないとダメでした
⑥Geocording APIを使用するための記述
% rails generate geocoder:config/config/initializes/geocoder.rbGeocoder.configure( # Geocoding options # timeout: 5, # geocoding service timeout (secs) lookup: :google, # name of geocoding service (symbol) # ip_lookup: :ipinfo_io, # name of IP address geocoding service (symbol) # language: :en, # ISO-639 language code use_https: true, # use HTTPS for lookup requests? (if supported) # http_proxy: nil, # HTTP proxy server (user:pass@host:port) # https_proxy: nil, # HTTPS proxy server (user:pass@host:port) api_key: 'YOUR_API_KEY', # API key for geocoding service # cache: nil, # cache object (must respond to #[], #[]=, and #del) # cache_prefix: 'geocoder:', # prefix (string) to use for all cache keys # Exceptions that should not be rescued by default # (if you want to implement custom error handling); # supports SocketError and Timeout::Error # always_raise: [], # Calculation options units: :km # :km for kilometers or :mi for miles # distances: :linear # :spherical or :linear )うまくいかない時の確認事項
・環境変数の設定
・viewの記述
・モデルのメソッド
・geocorder.rb%rails c [1] pry(main)> Geocoder.coordinates("〒150-0043 東京都渋谷区道玄坂2丁目1") => [35.6591376, 139.7007901]で中身を変えながら出力されるか試してみる
・Google Map javascriptと、Geocoding APIのAPIkeyを一緒にしている場合、APIをもうひとつ作成し、別々にしてみる。
・本番環境での環境変数設定[ec2-user@〜〜〜〜〜〜〜]$ sudo vim /etc/environment変数設定後exit→再起動
[ec2-user@〜〜〜〜〜〜〜]$ env | grep YOUR_API_KEYで確認
・EC2サーバーから再起動してみる(私はこれで最終的に本番環境で確認が取れました)
- 投稿日:2020-10-21T14:01:32+09:00
RSpecでコピペのテスト
権限によってペーストができなくなる機能のテストをしようと思ったら全然うまいこと行かずにかなりハマったのでメモ。
# コピー page.execute_script(' var copy_target = document.getElementById("copy_target"); copy_target.select(); document.execCommand("copy"); ') # ペースト find_by_id('paste_target').send_keys [:control, 'V']
- 投稿日:2020-10-21T13:22:36+09:00
Rails Tutorial 0章:事前基礎知識編①
1.事前基礎知識編
私がRailsを学び始めて最初に躓いたのが、ライブラリ・フレームワークといった謎の言葉達でした。
一つ一つGoogleで検索して言葉の意味を調べてもあまりしっくりきませんでした。Ruby on RailsとはWebアプリケーションフレームワークです。そもそもWebアプリケーションフレームワークとは、動的なウェブサイト、Webアプリケーション、Webサービスの開発をサポートするために設計されたアプリケーションフレームワークのことを言います。フレームワークは日本語では「枠組み」というふうに言われますが、まさにその通りで、このRailsもプログラミング言語のRubyで使えるフレームワークなのです。Railsの基本理念は「Don’t Repeat Yourself(DRY)」、「Convention over Configuration(CoC)」でそれぞれ「同じことは繰り返さない」、「設定より規約」という意味になります。
引用:https://techacademy.jp/magazine/7011理解力の乏しい私にはこの文章では理解できませんでした( ノД`)シクシク…
私の言葉で言い換えるとフレームワーク=テンプレート(雛型)です
みなさん、Microsoft WORDやEXCELなどを使って履歴書を一から作った事ありますか?
私は約15年前の学生時代にEXCELを使って自分で履歴書を一から作らさせられました。
今時代に履歴書を白紙状態から作るなんてことはないと思います。
履歴書の雛型(テンプレート)をダウンロードして必要な情報を埋めて履歴書を作りますよね?
それと同じでWEBアプリケーションも雛型を元に必要事項を埋める事で最低限の機能を持ったWEBアプリが作れる時代になっているみたいです。RailsはRubyというプログラミング言語でWEBアプリケーションを作る時によく利用されるテンプレート
余談ですが、Pythonというプログラミング言語ではRailsの利用はできません。
PythonではWEBアプリケーションを作る為にdjangoというフレームワークがよく利用されている様です。
フレームワークは共通概念も多いので一つフレームワークを使ったアプリ開発を行うと、こんな風にやるのね~とイメージが掴めて別のフレームワークで開発を使用する際にも活きるようです。また現在のWEBアプリケーションは様々な言語が組み合わされて作られているそうで、Railsは主にログインやユーザー管理部分などウェブアプリケーションに必要な基本的な部分を作る為に使われている様です。
例えば、最近話題のAI(機械学習)の機能を持ったウェブアプリケーションを作りたい場合は、
機械学習が得意なpythonというプログラミング言語で機械学習部分を作成し、ウェブアプリケーションの基本的な部分はRuby on Railsで作って組み合わせる事が可能とのこと。ライブラリって何?
フレームワーク」は、よく「ライブラリ」という言葉と混同されがちですが、ライブラリというのは特定の機能を提供し、プログラムの中でそれらを呼び出すことで動作するものです。
引用:https://techacademy.jp/magazine/7011これも私の言葉で言い換えるとライブラリ=パーツ(部品)です
また履歴書を例にしますが、氏名を書く欄、写真を張る場所、学歴・職歴を書く欄、趣味・特技を書く欄などの様々なパーツが組み合わさって履歴書というテンプレートが出来ています。
履歴書と同じようにWEBアプリケーションもいろんな部品が組み合わさってテンプレートが出来ています。
その個々の部品の事をライブラリと呼ぶ様です。
例えば、ログイン機能を簡単に実装する為にdeviseというライブラリ(部品)があります。
一から作ると(。´・ω・)ん?わけわからないどうやって動いてるの?
ってなるログイン機能もdeviseという部品を使うと比較的簡単に実装出来ます。プログラミング言語の得意分野・不得意分野
RubyはRailsがあるのでWEBアプリケーション開発が得意分野。
javaは大規模な分散処理が得意だったり、pythonは機械学習が得意らしいです。何故、プログラミング言語に得意分野・不得意分野があるかというと、アプリケーションはライブラリ(部品)を組み合わせて作るからです。pythonは機械学習用の多くの部品が既に存在し、天才達が新たな部品を開発したり、今ある部品を改善してくれてくれたりしています。一方でRubyは機械学習用ライブラリが少なく、同様の機能を実装する為には部品を一つ一つ自作していく必要があります。
このような差がプログラミング言語の得意・不得意を持つ要因となっている様です。セイト先生のWeb・IT塾主要プログラミング言語16選!特徴と初心者向けおすすめ度まとめ
プログラミング言語の得意分野などが開設されていて分かりやすい動画でした。
頭のいい方々は説明も上手なんですね。
【Web/IT業界あるある】締め切り、プログラミング中、エンジニア面接
学習の息抜きにこの動画も見てみました。
特に後半のエンジニア面接部分は非常に興味深かったです。
少しRuby on Railsを頑張ろうってモチベーションUPがアップしました。まとめ
- フレームワーク= WEBアプリケーション用に用意されたテンプレート
- ライブラリ = WEBアプリケーション用に利用できるパーツ
- Rails = Rubyで使えるWEBアプリケーション用フレームワーク
- 投稿日:2020-10-21T13:22:36+09:00
Rails Tutorial 0 - 基礎知識
1.Railsの基礎知識
私がRailsを学び始めて最初に躓いたのが、ライブラリ・フレームワークといった謎の言葉達でした。
一つ一つGoogleで検索して言葉の意味を調べてもあまりしっくりきませんでした。Ruby on RailsとはWebアプリケーションフレームワークです。そもそもWebアプリケーションフレームワークとは、動的なウェブサイト、Webアプリケーション、Webサービスの開発をサポートするために設計されたアプリケーションフレームワークのことを言います。フレームワークは日本語では「枠組み」というふうに言われますが、まさにその通りで、このRailsもプログラミング言語のRubyで使えるフレームワークなのです。Railsの基本理念は「Don’t Repeat Yourself(DRY)」、「Convention over Configuration(CoC)」でそれぞれ「同じことは繰り返さない」、「設定より規約」という意味になります。引用:https://techacademy.jp/magazine/7011
頭のいい方々は理解できるのかもしれませんが、理解力の乏しい私には理解できませんでした。
私の言葉で言い換えるとフレームワーク=テンプレート(雛型)です
みなさん、Microsoft WORDやEXCELなどを使って履歴書を一から作った事ありますか?
今の時代は流石にそんなことはないと思います。
履歴書の雛型(テンプレート)をダウンロードして必要な情報を埋めて履歴書を作りますよね?
それと同じでWEBアプリケーションもテンプレートをダウンロードして必要事項を埋めると最低限の機能を持ったモノが作れるようになっています。結論:RailsはRubyというプログラミング言語でWEBアプリケーションを作る時によく利用されるテンプレート
余談ですが、Pythonというプログラミング言語ではWEBアプリケーションを作る為にdjangoというフレームワークがよく利用されている様です。Railsはpythonというプログラミング言語では利用できません。ただし、フレームワーク自体の構造は似ている様なのでフレームワークというモノを利用してどうやってアプリケーションを作る事のかを利用する事はできるそうです。
ライブラリって何?
フレームワーク」は、よく「ライブラリ」という言葉と混同されがちですが、ライブラリというのは特定の機能を提供し、プログラムの中でそれらを呼び出すことで動作するものです。
引用:https://techacademy.jp/magazine/7011これも私の言葉で言い換えるとライブラリ=パーツ(部品)です
また履歴書を例にしますが、氏名を書く欄、写真を張る場所、学歴・職歴を書く欄、趣味・特技を書く欄などの様々なパーツが組み合わさって履歴書というテンプレートが出来ています。
履歴書と同じようにWEBアプリケーションもいろんな部品が組み合わさってテンプレートが出来ています。
その個々の部品の事をライブラリと呼ぶ様です。
例えば、ログイン機能を簡単に実装する為にdeviseというライブラリ(部品)があります。
一から作ると(。´・ω・)ん?わけわからないどうやって動いてるの?
ってなるログイン機能もdeviseという部品を使うと比較的簡単に実装出来ます。まとめ
- フレームワーク= WEBアプリケーション用に用意されたテンプレート
- ライブラリ = WEBアプリケーション用に利用できるパーツ
- Rails = Rubyで使えるWEBアプリケーション用フレームワーク
- 投稿日:2020-10-21T13:22:36+09:00
Rails Tutorial 0章:事前基礎知識編
1.事前基礎知識編
私がRailsを学び始めて最初に躓いたのが、ライブラリ・フレームワークといった謎の言葉達でした。
一つ一つGoogleで検索して言葉の意味を調べてもあまりしっくりきませんでした。Ruby on RailsとはWebアプリケーションフレームワークです。そもそもWebアプリケーションフレームワークとは、動的なウェブサイト、Webアプリケーション、Webサービスの開発をサポートするために設計されたアプリケーションフレームワークのことを言います。フレームワークは日本語では「枠組み」というふうに言われますが、まさにその通りで、このRailsもプログラミング言語のRubyで使えるフレームワークなのです。Railsの基本理念は「Don’t Repeat Yourself(DRY)」、「Convention over Configuration(CoC)」でそれぞれ「同じことは繰り返さない」、「設定より規約」という意味になります。
引用:https://techacademy.jp/magazine/7011理解力の乏しい私にはこの文章では理解できませんでした( ノД`)シクシク…
私の言葉で言い換えるとフレームワーク=テンプレート(雛型)です
みなさん、Microsoft WORDやEXCELなどを使って履歴書を一から作った事ありますか?
私は約15年前の学生時代にEXCELを使って自分で履歴書を一から作らさせられました。
今時代に履歴書を白紙状態から作るなんてことはないと思います。
履歴書の雛型(テンプレート)をダウンロードして必要な情報を埋めて履歴書を作りますよね?
それと同じでWEBアプリケーションも雛型を元に必要事項を埋める事で最低限の機能を持ったWEBアプリが作れる時代になっているみたいです。RailsはRubyというプログラミング言語でWEBアプリケーションを作る時によく利用されるテンプレート
余談ですが、Pythonというプログラミング言語ではRailsの利用はできません。
PythonではWEBアプリケーションを作る為にdjangoというフレームワークがよく利用されている様です。
フレームワークは共通概念も多いので一つフレームワークを使ったアプリ開発を行うと、こんな風にやるのね~とイメージが掴めて別のフレームワークで開発を使用する際にも活きるようです。また現在のWEBアプリケーションは様々な言語が組み合わされて作られているそうで、Railsは主にログインやユーザー管理部分などウェブアプリケーションに必要な基本的な部分を作る為に使われている様です。
例えば、最近話題のAI(機械学習)の機能を持ったウェブアプリケーションを作りたい場合は、
機械学習が得意なpythonというプログラミング言語で機械学習部分を作成し、ウェブアプリケーションの基本的な部分はRuby on Railsで作るという組み合わせるも可能との事です。ライブラリって何?
フレームワーク」は、よく「ライブラリ」という言葉と混同されがちですが、ライブラリというのは特定の機能を提供し、プログラムの中でそれらを呼び出すことで動作するものです。
引用:https://techacademy.jp/magazine/7011これも私の言葉で言い換えるとライブラリ=パーツ(部品)です
また履歴書を例にしますが、氏名を書く欄、写真を張る場所、学歴・職歴を書く欄、趣味・特技を書く欄などの様々なパーツが組み合わさって履歴書というテンプレートが出来ています。
履歴書と同じようにWEBアプリケーションもいろんな部品が組み合わさってテンプレートが出来ています。
その個々の部品の事をライブラリと呼ぶ様です。
例えば、ログイン機能を簡単に実装する為にdeviseというライブラリ(部品)があります。
一から作ると(。´・ω・)ん?わけわからないどうやって動いてるの?
ってなるログイン機能もdeviseという部品を使うと比較的簡単に実装出来ます。各プログラミング言語には得意分野があるそうです。
RubyはRailsがあるのでWEBアプリケーション開発が得意分野。
javaは大規模な分散処理が得意だったり、機械学習はpythonが得意らしいです。何故、プログラミング言語に得意分野・不得意分野があるかというと、
アプリケーションは部品をライブラリを組み合わせて作るからです。
pythonには多くの機械学習用ライブラリが存在し、今もなお天才の方々がライブラリを作ってくれています。
逆にRubyでは機械学習用ライブラリが少ないので同様の機能を全て自作していく必要があります。
このような差がプログラミング言語の得意・不得意に繋がっている様です。まとめ
- フレームワーク= WEBアプリケーション用に用意されたテンプレート
- ライブラリ = WEBアプリケーション用に利用できるパーツ
- Rails = Rubyで使えるWEBアプリケーション用フレームワーク
間違っていたらご指摘ください。( `・∀・´)ノヨロシク
- 投稿日:2020-10-21T13:08:56+09:00
link_toで改行したボタンを作りたい[備忘録]
link_toで改行したボタンを作りたい[備忘録]
改行を含んだボタンを作りたいなと思った時に、困ったので備忘録として記載します。
間違った例
<%= %>の中に改行させるべく</br>を入力するとそのまま出力されてしまいます。
<%= link_to "<h2>ログイン</h2></br>ログインすると、コメント・いいねが可能です!",new_user_registration_path, {class: "btn btn-success"} %>結論
原因は、エスケープ処理をしていないからです。
リンクするテキストにrawを含んでエスケープを無効化します。= link_to raw("リンクテキスト一行目<br/>リンクテキスト二行目"), hoges_path例
<%= link_to raw("<h2>ログイン</h2></br>ログインすると、コメント・いいねが可能です!"),new_user_registration_path, {class: "btn btn-success"} %>エスケープ文字って何?
特殊文字 <p>や<br>などの特殊文字の効果を無効化させることです。
- 投稿日:2020-10-21T12:55:41+09:00
Heroku上でのエラー解決方法
環境
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
手順
Heroku上でエラーが発生した際には、エラーログを確認してエラー解決を行う必要があります。
以下の5つの手順で解決可能です。1.エラー発生
Herokuへアクセスすると、下記の画像の内容が表示されました。
サイトでは、エラーの具体的な内容がわからないのでターミナルでエラーログを確認します。2.エラーログを出力
terminalheroku logs --tail --app <<アプリケーション名>>を入力するとエラーログが表示されます。
実際にエラーが起こったログを探します。
3.エラー発見
4.仮説
エラー内容はHeroku上にコメントテーブルが存在しないよとのことなので、Heroku上のデータベースにマイグレーションの内容が反映されていないと予測。
Heroku上でマイグレーションを実行を行えば、解決する可能性有り。実際に検証します。
5.検証
terminalheroku run rails db:migrate
実行後、再度アクセス。
無事解決!まとめ
Heroku上でエラーが起こった際の手順
大きく分けると3step
・エラーログを出力
・最新のエラーを発見
・仮説検証
以上です。最後まで読んでいただきありがとうございます!
同じような課題にぶつかっている方のお役に立てれば、嬉しいです!
- 投稿日:2020-10-21T11:49:53+09:00
CapistranoでEC2への自動デプロイ時、SSHキー認証エラーが出たときの対処法
共有すること
Railsで開発を行っていて、Capistranoを使用しAWSへの自動デプロイを実装しました。
あるとき突然、SSHキー認証エラーが起きてデプロイできなくなってしまったので、
その解決策を簡単に共有します。エラー内容
$ bundle exec cap production deployでデプロイ実行時、以下のようなエラーが出ました。
SSHKit::Runner::ExecuteError: Exception while executing as ec2-user@ElasticIP: Authentication failed for user ec2-user@ElasticIP解決策
ターミナルを再起動するとsshキーが消えてしまうようなので以下のようにすることで、登録し直しが必要でした。
ターミナルのローカルで
$ eval \`ssh-agent ` $ ssh-add -K ~/.ssh/<キーの名前>.pemこのようにすることで、sshキーを保存しておくことができまして、無事にデプロイできました!
会社の紹介
私は現在、株式会社ダイアログという物流×ITの会社に勤務しております。
2020年10月現在、エンジニアの募集はしていませんが、他にも様々な職種を募集しているので、Wantedlyのページをご覧ください。
- 投稿日:2020-10-21T11:00:29+09:00
include?メソッドの使い方
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。
include?メソッドについて自分なりにまとめました。include?メソッド
- 引数で指定した要素が配列や文字列内に入っているか判定するメソッド
array = ["dog", "cat"] puts array.include?("dog") # => true puts array.include?("hoge") # => false実際のコードでは
- 出力例 登録したい名前を入力してください(例)YamadaTaro
- この場合は入力した名前を受け取って「.」や「空白」があればエラー文を出力したいということですね。
def check_name(name) if name.include?(".") puts "!エラー!記号は登録できません" elsif name.include?(" ") puts "!エラー!空白は登録できません" else puts "登録が完了しました" end end puts '登録したい名前を入力してください' name = gets check_name(name)
- 2行目、checkメソッドの引数nameにinclude?の引数”.”(ピリオド)があればtrueを返してエラー文が出力されます。
- 4行目、同様に、nameにinclude?の引数” ”(空白)があればtrueを返してエラー文が出力されます。
- 投稿日:2020-10-21T01:41:25+09:00
RESTが分かればRuby on Rails チュートリアルの見通しがよくなる話
この記事を読んで得られること
「いきあたりばったり」にチュートリアルをこなすのではなく、一筋の光が通った状態でチュートリアルを進めることができるようになる(かも)
想定読者はWEB周りの予備知識があまりなく
Railsチュートリアル途中か終わってすぐぐらいの人
(私がそうです)RESTって何?
雑に言うと、webの設計思想のこと
RailsもRESTの思想に沿って設計されている実はRailsチュートリアル2章のコラム2.2(第4版の場合)にチュートリアルを
読みこなすのに必要そうなRESTの概要が書かれていますが
よくわからないままサッと見て先に進んだ人もいるのではないでしょうか
私は進みましたが、
RESTの概念はチュートリアル中ついて回っている(というか骨子とすら言える)ので
チュートリアル中に早めになんとなくでも掴んでおいたほうが
一貫した構造や著者が考えていることが見えてきて迷子になりにくいのではないかと思いますRESTの概念はかなり抽象的なのですぐ全部理解しなくてもよいと思いますが
わかるとチュートリアル内のことだけでなくチュートリアルの外の
web世界も少しクリアに見ることができてお得です以下、自分が感じたレベル別に解説していく
レベル1 HTTPリクエストとCRUD操作の関係の理解
レベル2 resourcesでルーティングされる内容の理解
レベル3 scaffoldで生成される謎のアクション群の理解
レベル4 RESTそのものの理解レベル1 HTTPリクエストとCRUD操作の関係の理解
ユーザがブラウザを操作するとHTTPリクエストが送られる
Railsチュートリアルではそのリクエストを元にデータベースを操作する部分を書いたり
ブラウザ操作手順をテストに書いて動作確認することがほとんどだこれだけわかればチュートリアル中の内容はとりあえず何とかなると思う
・8つあるHTTPリクエストのうちよく使われる4つ
HTTPリクエスト 処理 GET 取得 POST 登録 PUT 更新 DELETE 削除
・データベースに必要な操作
CRUD操作 処理 READ 取得 CREATE 登録 UPDATE 更新 DELETE 削除
・それぞれの対応
HTTPリクエスト CRUD操作 処理 GET READ 取得 POST CREATE 登録 PUT UPDATE 更新 DELETE DELETE 削除 レベル2 resourcesでルーティングされる内容の理解
Q:「routes.rb」に「resources :users」と書くだけで
なんで諸々よしなにルーティングしてくれるの?routes.rbRails.application.routes.draw do resources :users endA: Railsはresourcesと宣言するとデフォルトで勝手に
GETとPOSTとPUTとDELETEに基づいて気を利かせて
URLとコントローラーのアクションを対応付けて以下を生成してくれます
URL アクション HTTPリクエスト 名前付きルート 用途 /users index GET users_path ユーザ一覧画面を表示 /users/:id show GET user_path(user) 特定ユーザの画面を表示 /users/new new GET new_user_path 新規ユーザの登録画面を表示 /users/:id/edit edit GET edit_user_path(user) ユーザの編集画面を表示 /users create POST users_path ユーザの登録アクション /users/:id update PATCH/PUT user_path(user) ユーザの更新アクション /users/:id destroy DELETE user_path(user) ユーザの削除アクション レベル3 scaffoldで生成される謎のアクション群の理解
scaffoldを使うとusersコントローラの中に以下の7アクションが勝手に生成されると思います
def index
def show
def new
def edit
def create
def update
def destroy初めの頃は勝手にいろいろ作られて何がなんだかわからなかったと思いますが
ここまでくればそれぞれの関連が見えてきたと思います
この7つなのはRailsのテンプレートだからということみたいです。
(不要なアクションは削除できるし
必要なら自作アクションを追加することが可能)説明が前後してしまいますが
「routes.rb」に「resources :コントローラ名」と書くと7アクションすべてのルーティングになりますが
チュートリアル13章のように:onlyオプションをつけると必要なルーティングだけを生成できますroutes.rbRails.application.routes.draw do resources :microposts, only: [:create, :destroy] endレベル4 RESTそのものの理解
結局RESTって?
本来のRESTの設計原則は以下の4つあるようです
- アドレス指定可能なURIで公開されていること
- インターフェース(HTTPメソッドの利用)の統一がされていること
- ステートレスであること
- 処理結果がHTTPステータスコードで通知されること
引用元:REST入門 基礎知識
Railsチュートリアルで必要なのは上記のREST原則のうち
- インターフェース(HTTPメソッドの利用)の統一がされていること
だけです。(この記事もそこに焦点を当てています)
その他のことの詳細は引用元リンクをご参照くださいただ、これだけわかっていれば各種サービスのAPIもRESTを意識して作られていることが
多いようなので、ほかのRESTfulなサービスとの連携がしやすいということになりますまとめ
Railsを使うならRESTfulなスタイルを採用するのが前提ということが
なんとなくわかってもらえれば幸いです自分で作る部分もRESTに沿うし、Railsがよしなにやってくれる部分も
RESTに沿っているのでそのことを理解しながらチュートリアルを進めたほうがよさそうです
- 投稿日:2020-10-21T01:11:52+09:00
投稿機能アプリv 結合コード
本日は、実際に投稿機能を持ったアプリケーションにおける結合コードについて
学びを深め、実践してみた。
その中で、ポイントとなる点がいくつかあったので、ポイントごとにまとめていきたいとおもう。ポイント1:have_selector
ポイント2:Capibara
ポイント3:fill_inhave_selectorについて
have_selectorについてはHTMLにおけるクラスや、idを指定する際に使用する。
Capibaraについて
Capibaraのgemの導入によって要素の検索を行うことが可能となる。
Capibaraのfinderによって要素の検索を可能としていることが判ったが、その検索対象は本当に様々で、
数多くの要素の検索を可能とする。
例としてはHTMLのタグであったり、cssのプロパティ、他には、Slectタグのどれを選んだのかもテスト
することができる。また、要素の操作性能をテストすることも可能であり、例えば、clickなどの、クリックした際に反応を示すか(アニメーション?)どうかを
確認することができる。have_contentについて

は基本的に、テキストに対して指定する時に使用する。

テストのコードを細かく見ていったときに、実践して判ったことは
Fill_inで指定するのはラベルのtext、id, name など属性がそれぞれ存在するなかで、選択するのはいづれかでよいということがわかった投稿した内容のツイートの存在を確認するテストにおいては
コードの記述が、基本的にJavascriptと似ているという特徴がある。
例えば、JSでcontent_testといったようにclassを指定して、buildHTMLをおこなうように、
このテストコードでも該当のclassを指定してそこのclassにツイートが存在するかを確かめることができる。
→更にはback-ground-imageなどのようにURLを指定することで、画像のURL が存在するかどうかも確かめることが可能であるということもわかった。これまでは正常系のテストについて確認したが、ここからは異常系のテストについてまとめていこうと思う。(異常系のテストコードの写真)
ポイント1:beforeアクションの仕組み
ポイント2:have_link
ポイント3:all
ポイント4:find_link().click
ポイント5:rails_helper.rbについてbeforeについて
beforeアクションはテストをそれぞれ実行する前に働かせるものであるが



このように@tweet1,2と変数を作った時に、FactoryBotのなかにある:userの情報を取ってくることができるのは
Factoriesのtweets.rbでassociation :userの表記によって、userとtweetのアソシエーションが組まれているからである。

もし、アソシエーションがうまく組まれていなかったりして、Userの情報がちゃんと構成されていないとテストの結果は
うまくいかなくなってしまう。have_link について
例としてexpect(要素).have_linkの記述によって、要素の中に当てはまるリンクを確認することができる。

all について
allによって存在する同じ名前のclassを全て取得することができる。

これはmoreクラスの一つ目のボタンを重ねた時に編集という文字があり、
edit_tweet_pathへととぶリンクがあるかどうかを確認している。find_link() について
このfind_link().clickは
A要素に対してのみ使用可能である。
rails_helper.rb について
テストで使う共通のコードをまとめている。
- 投稿日:2020-10-21T01:11:52+09:00
投稿機能アプリ 結合コード 実践
本日は、実際に投稿機能を持ったアプリケーションにおける結合コードについて
学びを深め、実践してみた。
その中で、ポイントとなる点がいくつかあったので、ポイントごとにまとめていきたいとおもう。ポイント1:have_selector
ポイント2:Capibara
ポイント3:have_contenthave_selectorについて
have_selectorについてはHTMLにおけるクラスや、idを指定する際に使用する。
Capibaraについて
Capibaraのgemの導入によって要素の検索を行うことが可能となる。
Capibaraのfinderによって要素の検索を可能としていることが判ったが、その検索対象は本当に様々で、
数多くの要素の検索を可能とする。
例としてはHTMLのタグであったり、cssのプロパティ、他には、Slectタグのどれを選んだのかもテスト
することができる。また、要素の操作性能をテストすることも可能であり、例えば、clickなどの、クリックした際に反応を示すか(アニメーション?)どうかを
確認することができる。have_contentについて

 have_content
は基本的に、テキストに対して指定する時に使用する。実践してわかったこと


テストのコードを細かく見ていったときに、実践して判ったことは
fill_inで指定するのはラベルのtext、id, name など属性がそれぞれ存在するなかで、選択するのはいづれかでよいということがわかった投稿した内容のツイートの存在を確認するテストにおいては
コードの記述が、基本的にJavascriptと似ているという特徴がある。
例えば、JSでcontent_testといったようにclassを指定して、buildHTMLをおこなうように、
このテストコードでも該当のclassを指定してそこのclassにツイートが存在するかを確かめることができる。
→更にはback-ground-imageなどのようにURLを指定することで、画像のURL が存在するかどうかも確かめることが可能であるということもわかった。これまでは正常系のテストについて確認したが、ここからは異常系のテストについてまとめていこうと思う。
ポイント1:beforeアクションの仕組み
ポイント2:have_link
ポイント3:all
ポイント4:find_link().clickbeforeアクションについて
beforeアクションはテストをそれぞれ実行する前に働かせるものであるが

このように@tweet1,2と変数を作った時に、FactoryBotのなかにある:userの情報を取ってくることができるのは
Factoriesのtweets.rbでassociation :userの表記によって、userとtweetのアソシエーションが組まれているからである。

もし、アソシエーションがうまく組まれていなかったりして、Userの情報がちゃんと構成されていないとテストの結果は
うまくいかなくなってしまう。have_link について
例としてexpect(要素).have_linkの記述によって、要素の中に当てはまるリンクを確認することができる。

all について
allによって存在する同じ名前のclassを全て取得することができる。

これはmoreクラスの一つ目のボタンを重ねた時に編集という文字があり、
edit_tweet_pathへととぶリンクがあるかどうかを確認している。find_link().click について
このfind_link().clickは
A要素に対してのみ使用可能である。

- 投稿日:2020-10-21T01:02:20+09:00
CircleCIでEC2デプロイ時にエラー
はじめに
個人アプリにてCircleCIを導入し、
EC2にデプロイしようとした所、いくつかエラーが発生したので、解決策を記載します。環境
- ruby 2.6.2
- rails 5.2.4
- EC2
config.yml
version: 2 jobs: # build ジョブ: CircleCI 上で Docker コンテナを作成してテストする build: docker: - image: alpine steps: - checkout - run: name: Echo Test command: echo "CircleCI Test" # deploy ジョブ: EC2 に SSH 接続して、デプロイを実行する deploy: machine: image: circleci/classic:edge steps: - checkout # CircleCI に登録した秘密鍵を呼び出す - add_ssh_keys: # CircleCI に登録した環境変数を使って SSH - run: ssh ${USER_NAME}@${HOST_NAME} 'cd /var/www/myapp && git pull origin master' workflows: version: 2 # build_and_deploy ジョブ: 一番最初に呼ばれるジョブ build_and_deploy: # build ジョブと deploy ジョブを呼び出す jobs: - build - deploy: requires: # deploy ジョブより先に build ジョブを実行しろ! - build # master ブランチに push された場合のみ deploy ジョブを実行する filters: branches: only: master起こった問題と解決策
①ポートが開いてないことによるエラー
ssh: connect to host ************* port 22: Connection timed out【解決策】
EC2のセキリティグループのインバウンドを下記のように編集する。
注)セキリティ上、中間サーバーを使用するほうが好ましい
ポート範囲 ソース 22 マイIP xxx.xxx〜 ↓
ポート範囲 ソース 22 カスタム 0.0.0.0/0 ②秘密鍵が合わないことによるエラー
①EC2にて下記のコマンドを実行し、pem鍵を作成(他の鍵と競合する可能性がある為、circleci-keyなどの名前にする)
ssh-keygen -m pem②EC2にて下記のコマンドを実行し、①で作成した公開鍵(鍵名.pub)をauthorized_keysにコピー
cat ~/.ssh/circleci-key.pub >> authorized_keys③EC2にて下記のコマンドを実行し、①で作成した秘密鍵を表示
cat ~/.ssh/circleci-key④表示された秘密鍵をCircleCIのSSH-Keyに設定
(このとき-----BEGIN RSA PRIVATE KEY-----と-----END RSA PRIVATE KEY-----まで含める)最後に
私の場合、これでエラーが解消されましたので、
是非ためしてみてください。参考