20210510のRubyに関する記事は17件です。

【Rails6】deviseで独自カラムを追加して使用する方法 ③

これまで これまでに、deviseのインストール・Userモデルの作成・Viewの作成を行いました。 今回は、コントローラ・ルーティング・モデルのカスタマイズを行っていきたいと思います。 ▽前回の記事はこちら▽ 【Rails6】deviseで独自カラムを追加して使用する方法 ① 【Rails6】deviseで独自カラムを追加して使用する方法 ② ① Controller 作成 View を追加するrails g devise:controllers users コマンドを実行 $ rails g devise:controllers users Running via Spring preloader in process 5360 create app/controllers/users/confirmations_controller.rb #認証メール再送用 create app/controllers/users/passwords_controller.rb #パスワード変更関連用 create app/controllers/users/registrations_controller.rb #ユーザ登録関連用 create app/controllers/users/sessions_controller.rb #ログイン用 create app/controllers/users/unlocks_controller.rb #ロック解除メール再送用 create app/controllers/users/omniauth_callbacks_controller.rb #外部ログイン用 =============================================================================== Some setup you must do manually if you haven't yet: Ensure you have overridden routes for generated controllers in your routes.rb. For example: Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions' } end =============================================================================== 上記コマンドで、ひと通り devise 用の Controller ( 各ファイルに # でファイルの用途を記載しました ) が生成されます。 上記のコマンド結果に記載の通り、カスタマイズしたコントローラを反映させるためには、ルーティング設定をしないといけません。 ② routes.rb 編集 /config/routes.rb ファイルを編集していきます。 routes.rb_編集前 Rails.application.routes.draw do devise_for :users # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end routes.rb_編集後 Rails.application.routes.draw do devise_for :users, controllers: { confirmations: 'users/confirmations', passwords: 'users/passwords', registrations: 'users/registrations', sessions: 'users/sessions', unlocks: 'users/unlocks' } # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end 上記のように、カスタマイズするコントローラを記載していきます。 ③ コントローラのカスタマイズ 今回は、独自カラムを追加していますが、特段コントローラーを変更する必要はありませんが、 今回Devise用の レイアウトテンプレート を使いページを表示させるため、コントローラへレイアウトテンプレートを読み込ませる文を追記します。 また、 レイアウトテンプレートのページタイトルを <title><%= @page_title%> | Sample</title としてインスタンス変数を入れページ毎のページタイトルに対応させているので、コントローラ へ ページタイトルも追記します。 同じ作業になるので、例で /users/confirmations_controller.rb に追記します。 confirmations_controller.rb_編集前 # frozen_string_literal: true class Users::ConfirmationsController < Devise::ConfirmationsController # GET /resource/confirmation/new # def new # super # end # POST /resource/confirmation # def create # super # end # GET /resource/confirmation?confirmation_token=abcdef # def show # super # end # protected # The path used after resending confirmation instructions. # def after_resending_confirmation_instructions_path_for(resource_name) # super(resource_name) # end # The path used after confirmation. # def after_confirmation_path_for(resource_name, resource) # super(resource_name, resource) # end end confirmations_controller.rb_編集後 # frozen_string_literal: true class Users::ConfirmationsController < Devise::ConfirmationsController layout "devise" # GET /resource/confirmation/new def new @page_title = "確認メールが届かない場合" super end # POST /resource/confirmation # def create # super # end # GET /resource/confirmation?confirmation_token=abcdef # def show # super # end # protected # The path used after resending confirmation instructions. # def after_resending_confirmation_instructions_path_for(resource_name) # super(resource_name) # end # The path used after confirmation. # def after_confirmation_path_for(resource_name, resource) # super(resource_name, resource) # end end layout "login"とコントローラ内に記載すると、Rails側で devise.html.erbをレイアウトテンプレートとして認識します。 ④ モデルのカスタマイズ モデルへは、Deviseで使用する機能を追記します。 user.rb_編集前 class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end user.rb_編集後 class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :trackable, :confirmable, :lockable, :timeoutable end No 機能 説明 1 database_authenticatable デフォルト 2 registerable デフォルト 3 recoverable デフォルト 4 rememberable デフォルト 5 validatable デフォルト 6 trackable ログイン回数・ログイン日時・IPアドレスの記録 7 confirmable 認証メールの送信・メール認証の確認 8 lockable ログインの連続失敗によるロック・ロック解除メール送信  9 timeoutable 一定期間動作のないアカウントのログアウト 10 omniauthable 外部サービスの認証 (Twitter・Facebookなど) 上記の機能の説明を表にしてみました。 ここまで行うと、使用する機能・コントローラ・レイアウトテンプレートが反映されます。 長くなりましたので、記事を分けてご紹介しようと思います。 次回は、デバイスの設定 ( 独自カラムでログインできるようにする ) 行っていきたいと思います。 ▽次の記事はこちら▽ 【Rails6】deviseで独自カラムを追加して使用する方法 ④ ~ 申し訳ございません。公開までしばらくお待ちください。 ~
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

遅延ロードさせてWebアプリを高速化する

遅延ロードとは 基本的にwebアプリは表示するデータを読み込んでからページを表示します。 しかしそれだと重いデータを取得・表示する場合、ページの表示速度が落ちて重たい動作になります。 なので先に軽い部分だけを読み込みそのページに移動してから重いデータを読み込むことで すべてを表示するまでの時間は変わらない(むしろ少し落ちる)がページの移動速度を大幅に上げることができます。 体感上はかなりサクサクした動作になります。 ↓ツイッターの遅延ロード 実装 gemfile gem 'render_async' を書きbundle 次にrenderを書き直します。 変更前: index.html <%= render "data", posts:@posts %> これを index.html <%= render_async data_path %> or <%= render_async data_user_path(@user) %> このようにする。 次にルーティング routes get "data", to: "posts#data", as: "data" #↓パラメーターが必要な場合 get "data_user/:id", to: "posts#data_user", as: "data" controller def index #@posts = Post.all end def data @posts = Post.all render partial: "data", locals: {posts:@posts} end def data_user @user = User.find_by(name: params[:id]) @posts = @user.posts.all render partial: "data_user", locals: {posts:@posts} end 最後はレイアウトに application.html.erb <%= content_for :render_async %> を追加。 これだけで遅延ロードが完成します。 turbolinksを使用している場合 このままだと時々表示されない場合があります。 <%= render_async data_path, html_options: { 'data-turbolinks-track': 'reload' } %> html_options: { 'data-turbolinks-track': 'reload' }を追加して config/initializersにrender_async.rbを作りましょう render_async.rb RenderAsync.configure do |config| config.turbolinks = true # Enable this option if you are using Turbolinks 5+ end jqueyを使う kaminariやjscrollで無限スクロールなどを実装している場合、これをしないと動きません。 config/initializers/render_async.rb RenderAsync.configure do |config| config.jquery = true end まとめ 遅延ロードって大きなサービスだと結構使われているのに日本語の情報が少なくて困ったので書きました。 体感上の動作速度がかなり変わるのでぜひやってみてください。 宣伝 AmmotというSNSを作りました。 文字数制限が6000字まで、画像・動画・PDF・音声は同時に10個まで投稿可能な自由なSNSです。 マークダウンにも対応しているので皆さん大好きなソースコードもきれいに載せれます。 ぜひ使ってみてください。 僕のツイッターアカ https://twitter.com/yamada1531
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Railsのバリデーションとエラーメッセージについて

例えばこれは簡単なToDoアプリですが、新規追加画面でバリデーションをかけて空欄、または5文字以上入力しないと登録できないようにします。 バリデーションとはデータ内容に一定の制限をかけることです。空のデータを登録できないようにする、パスワード入力において文字数制限をかけるなどです。 バリデーションの記述はappディレクトリのmodelsにあるファイルに記述します。 class Task < ApplicationRecord validates :title, presence: { message: 'タイトルを入力してください'}, length: { minimum: 5, message: '5文字以上入力してください'} end validates :title,でtitleカラムにバリデーションをかけるという意味 presenceで空のデータは登録できないという意味{ message: 'タイトルを入力してください'},でエラーメッセージが表示されます。 length: { minimum: 5, message: '5文字以上入力してください'}で5文字以下の場合はエラーメッセージが表示されるようになります。 続いてviewファイルの記述 <p> <%= f.label :title %> <br> <%= f.text_field :title %> <% if @task.errors.any? %> <%= @task.errors.messages[:title][0] %> <% end %> </p> <p> <%= f.submit%> </p> 入力欄text_fieldの下にエラーメッセージを出力させます。 <% if @task.errors.any? %> <%= @task.errors.messages[:title][0] %> <% end %> @taskモデルにエラーがあった時エラーメッセージを表示させる記述になります。 入力が空の場合 5文字未満の場合
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Active Recordのメソッドと実行されるSQL一覧

はじめに 多くのRails初学者はSQL文をあまり意識せずActive Recordを使用してしまっているかと思います。しかしデバッグ作業や複雑な絞り込みには生のSQL文を利用する機会はそれなりに多く、また実行されているSQLを理解していないままだと気づかぬうちに非効率なコードを書いてしまっている可能性があります。 そこで本記事ではActiveReocordメソッドで実行されているSQL文をまとめてみました。 メソッドとSQL文 find User.find(1) # SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 User.find([2,3,4]) # SELECT `users`.* FROM `users` WHERE `users`.`id` IN (2, 3, 4) findメソッドでは「引数をidに持つレコードを取り出す」というSQLが実行されています。 指定したidが単数の場合はSQL文にLIMIT 1 が付加されますが、配列で複数指定した場合は付加されません。 find_by User.find_by(id:3) # SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 User.find_by(id:[3,4,6]) # SELECT `users`.* FROM `users` WHERE `users`.`id` IN (3, 4, 6) LIMIT 1 find_byメソッドではカラム名を指定してレコードを取り出します。条件ハッシュに配列を渡すことが可能ですが LIMIT 1が付加されるので一つのレコードしか呼び出されません。 where User.where(email:"test@test.com") # SELECT `users`.* FROM `users` WHERE `users`.`email` = 'test@test.com' Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight) # SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00') whereメソッドは文字通りSQLのWHERE句の部分に相当します。 order User.order(:username) # SELECT `users`.* FROM `users` ORDER BY `users`.`username orderメソッドではSQLのORDER BY句が実行され、指定された属性の昇順でレコードが並び替えられます。 first,last User.first # SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 User.last # SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1 firstメソッドではidで昇順に並べたレコードの最初の一つを取り出すSQLが実行されます。lastは降順の一番最初となります。 save,update user = User.find(2) user.username = "test" user.save # UPDATE `users` SET `users`.`updated_at` = '2021-05-09 07:08:50', `users`.`username` = 'test' WHERE `users`.`id` = 2 saveメソッドではインスタンス変数が変更された場合に、レコードを更新するSQLのUPDATE句が実行されます。 select, pluck User.select(:username) # SELECT `users`.`username` FROM `users` selectメソッドではテーブから対象となるカラムのみを取り出します。pluckも同様のSQL文が発行されますが指定したカラムの値の配列を返すという点が異なります。 User.select("date(created_at) as ordered_date") # SELECT date(created_at) as ordered_date FROM `users` また、文字列でasを使った条件を渡すことでSQLの関数DATEの引数に渡したcreate_atをordered_dateという別の名前を付けて取得することができます。 destroy User.find(3).destroy # DELETE FROM `profiles` WHERE `profiles`.`id` = 3 destoryメソッドではSQLのDELETE文が実行されます。 limit, offset User.limit(2).to_sql # "SELECT `users`.* FROM `users` LIMIT 2" limitメソッドでは指定された件数のみレコードが取り出されます。 User.offset(2).limit(3).to_sql # "SELECT `users`.* FROM `users` LIMIT 3 OFFSET 2" offsetメソッドではレコードを返す前にスキップするレコード数を指定することが可能です。 上のコードでは、2つのレコードがスキップされ、id=3から3つのレコードが取得されます。 また、これらを組み合わせることでページネーション機能を実装することが可能です。 例えば、ページネーションに使用されるgemであるkaminari を使用した場合 User.page(3).per(5) # SELECT `users`.* FROM `users` LIMIT 5 OFFSET 10 このようなSQLが発行されます。 exsits? User.exists?(id:1) # SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1 exists?メソッドは、渡された条件ハッシュを満たすレコードが存在するかどうかを確認するメソッドです。 WHERE句をみると。対象となるテーブルから条件を満たすレコードを一つ絞り込んでいます。そして1 AS oneから分かる通り、1をoneという別の名前を付けて取り出しています。 group, count ,having User.select("date(updated_at) as date, sum(id)").group(:date) # SELECT date(updated_at) as date, sum(id) FROM `users` GROUP BY `date` Userの更新日のコレクションごとに更新日、コレクションのidの合計を検索する場合は上記のようなSQL文を発行します。 User.group("date(updated_at)").count # SELECT COUNT(*) AS count_all, date(updated_at) AS date_updated_at FROM `users` GROUP BY date(updated_at) 上記ではgroupメソッドとcountメソッドを組み合わせることで、更新日のコレクションごとのレコード数,更新日を取得するSQL文を発行します。 User.select("date(updated_at) as date, sum(id)").group(:date).having("sum(id)>10") # SELECT date(updated_at) as date, sum(id) FROM `users` GROUP BY `date` HAVING (sum(id)>10) havingメソッドを使うことで集約した結果に対して条件指定を行うHAVING句が付加されます。 joins/left_outer_joins 以下のような二つのテーブルがあるとします。 Owner table id ownername 1 ichijo 2 jiro 3 saburo Dog table id owner_id dogname 1 1 pochi 2 2 maru 3 2 hachi 4 4 ken SELECT * FROM owners INNER JOIN dogs ON owners.id = dogs.owner_id; このようにINNER JOINが実行された場合は、結合キーとなっているそれぞれのテーブルのキー値のうち、両方のテーブルに存在する値を持つレコードのみが結合されます。 上記のSQL文ではそれぞれのキーの共通している値は1,2のみであるので、Dogテーブルからはowner_idが1,2のテーブル、Ownerテーブルからはidが1,2のテーブルが結合され、以下のようなテーブルが出来上がります。 id ownername id owner_id dogname 1 ichiro 1 1 pochi 2 jiro 2 2 maru 2 jiro 3 2 hachi SELECT * FROM owners LEFT OUTER JOIN dogs ON owners.id = dogs.owner_id; 一方でOUTER JOINの場合はINNER JOINで結合されるレコードに加え、基準となるテーブル(LEFT OUTER JOINの場合は左側のテーブル)のキー値を持つテーブルが結合されます。 つまり、今回の場合は基準となるOwnerテーブルのデータはレコードは全て取得され、それに対応するDogsテーブルのレコードが結合されます。 id ownername id owner_id dogname 1 ichiro 1 1 pochi 2 jiro 2 2 maru 2 jiro 3 2 hachi 3 saburo null null null このように、基準となるテーブルのレコードは全件取得され、対応するレコードがない部分はnullとなります。 それぞれの結合に対応するActive Recordメソッドは以下のようになります。 Product.joins(:reviews) # SELECT `products`.* FROM `products` INNER JOIN `reviews` ON `reviews`.`product_id` = `products`.`id` ProductモデルがReviewsモデルに対してhas_manyの関係を持っている場合、joinsメソッドでは内部結合を行うINNER JOIN句を呼び出しています。 Product.left_outer_joins(:reviews) # SELECT `products`.* FROM `products` LEFT OUTER JOIN `reviews` ON `reviews`.`product_id` = `products`.`id` left_outer_joinメソッドでは左のテーブルを基準としたOUTER JOIN句が呼ばれます。 なお、joins, left_outer_joinsメソッドを使用した場合に発行されるSQL文から、SELECTで結合先のテーブルデータを取得していないことがわかります。selectメソッドを使用して以下のようにすると結合した全てのカラムデータを取得することができます。 Product.select("*").joins(:reviews) # SELECT * FROM `products` INNER JOIN `reviews` ON `reviews`.`product_id` = `products`.`id` Product.select("*").left_outer_joins(:reviews) # SELECT * FROM `products` LEFT OUTER JOIN `reviews` ON `reviews`.`product_id` = `products`.`id` 参考 最近の未経験エンジニアはSQLの理解が浅すぎる!!【サーバーサイド言語Ruby/PHPを勉強している人向け】 Active Record クエリインターフェイス SQL素人でも分かるテーブル結合(inner joinとouter join) SQL ゼロからはじめるデータベース操作
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

includesを用いてN+1問題を解消する

関連付によって構文が異なるincludesメソッド N+1問題を解消する目的で、メインページでのfeedメソッドにincludesを導入しました。 伝えられる事としましては、関連付けの種類によってincludesの構文が変わるという事です。 controller.rb def home : @feed_items = current_user.feed.page(params[:page]) : end before user.rb(変更前 def feed Work.where( "user_id = ? OR user_id IN (?)", id, Relationship.where(follower_id: id).select(:followed_id) ) end after user.rb(変更後 def feed Work.includes( [ :comments, :likes, image_attachment: :blob, user: { avatar_attachment: :blob }, illustrations: { photo_attachment: :blob } ] ).where( "user_id = ? OR user_id IN (?)", id, Relationship.where(follower_id: id).select(:followed_id) ) end このアプリケーションのER図です。 (自動生成されたものなので見ずらいかもしれません。すいません。 今回は以上です!! 目を通して頂きありがとうございました!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】部分文字列 (paizaランク D 相当)【解答】

はじめに 問題文はこちらから 解答 a = gets.chomp b = gets.chomp if b.include?(a) puts "YES" else puts "NO" end getsメソッドを使って出力値をaとbに代入させてあげて、 条件式とinclude?メソッドを使って、特定の文字か含まれていたら"YES"を返してあげる。 include?メソッドの使い方も記載しました。 include?メソッド 文字列の中に、特定の文字列を含むかどうかを調べるメソッド。 含まれる場合は"true"、含まれない場合は"false"を返してくれます。 a = "abc123" a.include?("abc") => true a.include?("d") => false a.include?("123") => true a.include?("234") => false
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【rails6】フラッシュメッセージの実装

こんにちは! 今日は”フラッシュメッセージ”の実装方法についてご説明します まずはフラッシュメッセージは何なのか、完成系をご覧ください 青いバーに白い文字のやつがフラッシュメッセージです では、実装していきましょう! 環境 Ruby on Rails 6.0 (使用したい人だけ、jQueryも必要です) ローカルでもHerokuでもEC2でも、なんでも大丈夫です 手順① flashメッセージの「key」 と 「value」を決める フラッシュメッセージで大切なことです。予め考えておきましょう! 下記、一例を載せておきます 【成功】 key: notice や success など 【失敗】 key: alert や error など 【成功】 value: ”投稿に成功しました” や "ログインに成功しました" 【失敗】 value: "削除に失敗しました" や "ログインに失敗しました" 手順② ビューファイルのどこに配置するか決める 以下、私の記述をコピペしてしまってください。 app/views/articles/index.html.erb <%= render "shared/post-bar" %> # ↓ 以下がflashメッセージの記述です。 ↓ <div class="flash-notifications"> <% flash.each do |key, value| %> <%= content_tag(:div, value, class: key) %> <% end %> </div> # ↑ コピペ以上 ↑ <div class='main'> # 省略 </div> 配置できたら、次にいきましょう! 手順③ コントローラーの編集 それでは、「何かの処理をした後にメッセージを表示させる」という指示を書いていきます articles_controller.rb def create @article = current_user.articles.build(article_params) if @article.valid? @article.save return redirect_to root_path, notice: '記事を投稿しました' # ←ここがflashメッセージ else render :new end end 簡単に解説しますと、 @articleに問題がなかったら(valid? => true)、保存(save)して、 root_pathに戻ってね、「notice: '記事を投稿しました'」を渡してね というものです。 「 valid? => false 」の場合も書くべきだと思いますが、 私は別の方法でエラーメッセージを表示させているので、フラッシュメッセージは省略しました。 ここまでやれば表示はできるようになります! この先は必要な方だけご覧ください cssも編集していきましょう! 手順④ cssを編集する application.scss .flash-notifications { font-weight: bold; color: white; text-align: center; .notice { background-color: #ADD8E6; } .alert { background-color: #FF4500; } } 私はどこのページでも共通する物と思ったので、「 application.scss 」の中に記述しました ※皆様にお任せします これで動画のように 水色ベース、白太文字で表示をする事ができました ただし、表示できるだけです 消えません ※ページをリロードすると消えるようになります 使い勝手の観点から、下記を追加実装しました 手順⑤ フラッシュメッセージをフェードアウトさせたい さて、以下はまた必要な方向けです 下記の記述を 「 application.js 」に記述してください ※jQuery未導入の方は、先にjQueryを導入してください! ↓ 以下をコピペ、ファイルの一番下で構いません ↓ app/javascript/packs/application.js $(function(){ setTimeout("$('.notice').fadeOut('slow')", 2000); }); $(function(){ setTimeout("$('.alert').fadeOut('slow')", 2000); }); classの名前は間違えないようにしてくださいね では、簡単に解説します setTimeout(hogehoge, 2000); これは、2.0秒後にhogehogeを実行させるという記述です msecの単位になってるので、2秒後は2000となりますね fadeOut('slow') こちらの記述ですが、読んで字のごとく、スローにフェードアウトさせます このslowですが、600msecで処理してくれるそうです slow : 600 msec normal : 400 msec fast : 200 msec の3つがあるそうです 下記の文献も参考として見ておいてくださいね! この参考文献 フロント側の設定は以上でOKですね 基本はこれでコンプリートです さて、次が最後です!頑張りましょう!! Devise関連のフラッシュメッセージの表示 ここでの必要項目 日本語化完了済み(gem 'rails-i18n'導入済み) config/locales/devise.ja.ymlのベースは記述済み さて、deviseを実装している場合、devise関連のフラッシュメッセージは標準装備されています。 言葉を書き換えればすぐにできるんです! 上記の「 config/locales/devise.ja.yml 」を編集していきます config/locales/devise.ja.yml ja: activerecord: devise: sessions: signed_in: "ログインに成功しました" # ここを書き換えます 他の箇所は省略しますが、この順番で探してみてください。 githubからコピペした場合は「 signed_in: "" 」 となっているはずです ここを上記のように好きな言葉に書き換えてください。 もちろん、その下の「 signed_out: "" 」も書き換えて良いと思います! 今日の解説は以上です! 引き続き頑張っていきましょう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails の link_to メソッドで :delete や :put を指定しても GET のリクエストが送信されてしまう理由と対策

最近Railsの学習を始めたのですが、ログアウト機能を実装していた際にハマったので、メモとして残します。 問題の概要 railsのlink_toメソッドを使って、以下のようにログアウト用のリンクを実装しました。 application.html.erb <%= link_to 'ログアウト', logout_path, method: :delete, class: 'nav-link' %> method: :delete として、HTTPメソッドをDELETEに指定しているのですが、なぜか最終的にGETになってリクエストが送られるという現象に遭遇しました。 ちなみにlink_toメソッドを使って生成されたHTMLのソースを確認したところ <li class="nav-item"> <a class="nav-link" rel="nofollow" data-method="delete" href="/logout">ログアウト</a> </li> となっており、きちんとaタグでdata-method="delete"となっていました。 解決法 いろいろと情報を探っていると、RailsではJavaScriptを使って、サーバーにリクエストを送信することもあるようです。 なので、JavaScriptを導入できていなかった場合に上記のようなHTTPメソッドのerrorが起こってくるようです。 自分の場合、Webpackerを導入しようとしていて、どこかで、手順の漏れがあったようです。 結局、現在制作中のアプリ(Rails学習のため作成)にはWebpackerを導入する必要性がなさそうだったので、Rails newを実行した時にデフォルトで記載されていた、以下の記述に戻して application.html.erb <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> app/asset/config内のapplication.jsに以下の記述を追加するとしっかりとDELETEでリクエストが送信できました。 application.js //= require jquery //= require jquery_ujs
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rakefileでnamespace外のタスクを指定

Rakefileでnamespaceを使ったときにハマることがあります。 namespaceの内と外で同じタスク名(例えばfoo)を定義 そのnamespaceの中から外のfooを参照したい 以下のようなことです。 Rakefile task :foo do puts '外のfoo' end namespace :bar do task :foo do puts 'bar:foo' end task baz: [:foo] do puts '"外のfoo" と表示されているはず' end end しかし rake bar:baz の結果は console $ rake bar:baz bar:foo "外のfoo" と表示されているはず つまりタスク bar:foo が外側のタスク foo をマスクします。こういうときはルートのnamespaceからのタスク名を指定(絶対指定)するか相対指定すると良いです。参照: Rakefile Format > Name Resolution 絶対指定の例を記します。ルートのnamespaceは rake ですので、タスク bar:baz の依存タスクの指定は - task baz: [:foo] do + task baz: ['rake:foo'] do のようにすればよいです。相対指定の例は省略します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyがミニツク Ruby入門 7~

クラスとモジュール1 クラスの定義 クラス名は最初の文字が大文字でないといけない。 class HelloRuby def hello puts 'Hello, Ruby!' end end greeting = HelloRuby.new greeting.hello #=> Hello, Ruby! initializeメソッド 他の言語でいうコンストラクタ。初期化の必要がなければinitializeメソッドを定義しなくてもいい class Person #引数に値を代入すると、デフォルト値を設定できる def initialize(name='Bob') @name = name end def name puts @name end end bob = Person.new bob.name #=> Bob john = Person.new('John') john.name #=> John インスタンス変数 名前の先頭に「@」がついている変数をインスタンス変数と呼ぶ。インスタンス変数はクラス内の異なるメソッドの間でも値を受け渡すことができる。インスタンス変数はインスタンスごとに異なる値を扱える。 class Foo def initialize(arg) @foo = arg end def foo puts @foo end def bar puts @foo end end foo = Foo.new('foo') foo.foo #=> foo foo.bar #=> foo bar = Foo.new('bar') bar.foo #=> bar bar.bar #=> bar #異なる値をインスタンス変数に代入している foo.foo #=> foo アクセサメソッド Rubyではインスタンス変数を外部から直接操作することができない。オブジェクトを操作するためにはメソッドを定義する必要がある。getter, setterを通して値を取得したり、書き換えろということ。 class Person def name return @name end def name=(value) @name = value end end nameメソッドとname=メソッドは同じではない。 nameメソッド:インスタンス変数を取得するメソッド(getter) name=メソッド:インスタンス変数に代入するメソッド(setter) class Person def name return @name end def name=(value) @name = value end end john = Person.new john.name = 'John' p john.name #=> John bob = Person.new bob.name = 'Bob' p bob.name #=> Bob けど、いちいちメソッドを定義するのは面倒だから、この機能を提供するのがアクセサメソッド。 attr_reader :method #=> 参照のみ attr_writer :method #=> 変更のみ attr_accessor :method #=> 参照&変更 アクセサメソッドを定義すると、引数に指定したメソッド名と同じインスタンス変数とメソッドが定義される。 class greeting attr_reader :hello attr_writer :bye attr_accessor :pardon end greeting = Greeting.new greeting.hello #=> nil greeting.bye = 42 greeting.pardon = 'sorry' p greeting.pardon #=> sorry クラスとモジュール2 オーバーライド サブクラスでスーパークラスのメソッドを書き換えることをオーバーライドという。 superと書くことで元のメソッドを実行できる。 class Foo def foo puts("foo") end end class Bar < Foo def foo super puts("foo") end end bar = Bar.new bar.foo 引数を渡さずにオーバーライドされたメソッドを呼び出すには、super()と書く。superと書いて()を省略すると、サブクラスのオーバーライドしたメソッドのデフォルト引数が渡される。 class Foo def foo(args=5) p args * 2 end end class Bar < Foo def foo(args=2) super(10) super super() end end bar = Bar.new bar.foo #=> 20 #=> 4 #=> 10
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyがミニツク Ruby入門 7~8章

クラスとモジュール1 クラスの定義 クラス名は最初の文字が大文字でないといけない。 class HelloRuby def hello puts 'Hello, Ruby!' end end greeting = HelloRuby.new greeting.hello #=> Hello, Ruby! initializeメソッド 他の言語でいうコンストラクタ。初期化の必要がなければinitializeメソッドを定義しなくてもいい class Person #引数に値を代入すると、デフォルト値を設定できる def initialize(name='Bob') @name = name end def name puts @name end end bob = Person.new bob.name #=> Bob john = Person.new('John') john.name #=> John インスタンス変数 名前の先頭に「@」がついている変数をインスタンス変数と呼ぶ。インスタンス変数はクラス内の異なるメソッドの間でも値を受け渡すことができる。インスタンス変数はインスタンスごとに異なる値を扱える。 class Foo def initialize(arg) @foo = arg end def foo puts @foo end def bar puts @foo end end foo = Foo.new('foo') foo.foo #=> foo foo.bar #=> foo bar = Foo.new('bar') bar.foo #=> bar bar.bar #=> bar #異なる値をインスタンス変数に代入している foo.foo #=> foo アクセサメソッド Rubyではインスタンス変数を外部から直接操作することができない。オブジェクトを操作するためにはメソッドを定義する必要がある。getter, setterを通して値を取得したり、書き換えろということ。 class Person def name return @name end def name=(value) @name = value end end nameメソッドとname=メソッドは同じではない。 nameメソッド:インスタンス変数を取得するメソッド(getter) name=メソッド:インスタンス変数に代入するメソッド(setter) class Person def name return @name end def name=(value) @name = value end end john = Person.new john.name = 'John' p john.name #=> John bob = Person.new bob.name = 'Bob' p bob.name #=> Bob けど、いちいちメソッドを定義するのは面倒だから、この機能を提供するのがアクセサメソッド。 attr_reader :method #=> 参照のみ attr_writer :method #=> 変更のみ attr_accessor :method #=> 参照&変更 アクセサメソッドを定義すると、引数に指定したメソッド名と同じインスタンス変数とメソッドが定義される。 class greeting attr_reader :hello attr_writer :bye attr_accessor :pardon end greeting = Greeting.new greeting.hello #=> nil greeting.bye = 42 greeting.pardon = 'sorry' p greeting.pardon #=> sorry クラスとモジュール2 オーバーライド サブクラスでスーパークラスのメソッドを書き換えることをオーバーライドという。 superと書くことで元のメソッドを実行できる。 class Foo def foo puts("foo") end end class Bar < Foo def foo super puts("foo") end end bar = Bar.new bar.foo 引数を渡さずにオーバーライドされたメソッドを呼び出すには、super()と書く。superと書いて()を省略すると、サブクラスのオーバーライドしたメソッドのデフォルト引数が渡される。 class Foo def foo(args=5) p args * 2 end end class Bar < Foo def foo(args=2) super(10) super super() end end bar = Bar.new bar.foo #=> 20 #=> 4 #=> 10 アクセス制限 public(デフォルト):どこからでも呼び出せる private:クラスの中、そのクラスを継承したサブクラスの中で呼び出せる protected :よくわからん というわけで、調べてみたらいい記事が見つかった。 Rubyでのprivateとprotectedの使い分け private と protected の使い方まとめ 上のページの引用文(Matzの) つまり,privateは自分からしか見えないメソッドであるのに対し て,protectedは一般の人からは見られたくないが,仲間(クラスが 同じオブジェクト)からは見えるメソッドです. private:インスタンスだけが見える protected:仲間(同じクラスのインスタンス)が見える
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsのルーティングnamespaceってなんで使うの?

はじめに Vue.jsをRailsで使うときにバックエンドをRailsのAPIモードで作り、 フロントエンドをVue.jsで作る記事をよく見かけた。 その際にルーティングでnamespaceを使っていたけれど なぜnamespaceを使うのかよくわからず、苦手意識があったので理解するためまとめてみました。 まずはAPIとはそもそもなんぞやというところからはじめてみましょう。 APIとは APIはApplication Programming Interfaceの略です。 ソフトウェアの機能を共有できる仕組みのこと。よく使われているものだとGoogle Mapなど。 郵便番号を入れると自動で入力されるなんてことができるのもこれのおかげだったり。 APIは通常Webに公開されていて、誰でも無料で使うことが可能。「WebAPI」と呼ばれたりもします。 一般的にJSONという形式で結果を返します。 RailsのAPIモードとは RailsのAPIモードはそのAPIをRailsで作成できるAPI作成に特化したモードのこと。 APIモードではMVCのViewg作成されません。 そのため、sass-railsやwebpacker、capybabaraなどはGemfaileには生成されません。 Rails4まではrails-apiというgemを入れる必要があったみたいですが 現在のバージョンでは特に何もしなくても使えます。 rails new アプリケーション名 --api と打つだけでAPIモードのRailsアプリケーションが作成されます。 次にそもそもnamespaceってなにという疑問を解消していきます。 Railsのルーティング RailsのルーティングはMVCモデルの基本の基本と言えるもので Viewから送られたリクエストを適切なコントローラーに送り、どんなアクションを行うかを管理するものです。 ルーティングはRailsアプリケーションのconfigディレクトリの中にあるroutes.rbに記述します。 Railsルーティング種類は調べてみるとたくさんありました。 urlを直接指定する root resouce resouces collection member new param shallow namespace scope concern constraints などなどたくさんあります。深そうですね。。。 scopeとnamespaceの違い ルーティングのまとめは別の機会にするとして 今回はその中でnamespaceにフォーカスを当てていきますが、 namespaceと似たようなscopeとの比較してみます。 scope namespace URL 指定のパス          指定のパス コントローラ   通常のcontroller内    controllerの中の指定のフォルダ scopeもnamespaceもURLを指定のパスにできますが namespaceはファイル構成も変えたい場合にいいみたいです。 scopeでもいいような気もしますね。 APIのバージョン railsのAPIを調べているとnamespaceを使ったroutes.rbの Rails.application.routes.draw do namespace 'api' do namespace 'v1' do resources :posts end end end などのところにあるv1という記述。 調べてみるとバージョン1の意味でした。 バージョン管理をするためにscopeではなく、namespaceを使っているのかとAPIのバージョン管理とは なんぞやと調べていきます。 Web APIのバージョン管理の重要性 Web APIとはアプリケーションのインターフェイスの役割を持ち、追加、変更、廃止などされていくものです。 通常のアプリもver.1.0.8とか書かれていますよね。 セマンティックバージョニングと言います。 バージョン管理を特にせず、管理者がこっちの方がいいから変更しよう〜とAPIを書き換えてしまったら そのAPIを使っているユーザーがいきなり使えなくなってしまう可能性があります。 例えばFacebookやGoogleなどのAPIが急に変更されると エラーが出て処理が止まったり、表示がおかしくなるなどの不具合が発生します。 それを防ぐために公開されているAPIは複数のバージョンを提供して、 そういう事態を招くことを防いでいるわけです。 APIのURI一覧 DMMのAPI https://api.dmm.com/affiliate/v3/ItemList?api_id=[APIID]&affiliate_id=[アフィリエトID]&site=DMM.R18&service=digital&floor=videoa&hits=[検索数]&sort=date&keyword=[キーワード]&output=[jsonかxml] TwitterのAPI https://api.twitter.com/2/tweets/search?tweet.fields=created_at,author_id,lang&query=$QUERY" YouTubeのAPI https://developers.google.com/youtube/v3/docs/ FacebookのAPI https://graph.facebook.com/v2.0/me とURIの中を見てみると、v○とあります。 いくつかバージョンの管理方法があるようなのですが URIにバージョンを埋め込むのがよく利用される方法のようです。 まとめ これらから考えられることはWeb APIは一人のユーザーが利用するものでなく、 アプリケーションと同様に多くの人が利用するために作られるためバージョン管理がされている。 その慣例としてv1などのバージョンをつけてルーティングをつけている。 それを実現するにはscopeよりもnamespaceが良いため、namespaceでルーティングをしていることが考えられる。 終わりに RailsでAPIを作るとなったときに 知らないnamespaceなどが出てきてよくわからなくて混乱しましたが なぜそうしているのかを時間はかかりますが紐解くのは大事です。 さまざまな記事を読ませていただいたのですが、それ違うなどもあると思いますので ぜひご指摘いただけたら嬉しいです。 参考サイト Railsのルーティングの種類と要点まとめ 初心者じゃなくても役に立つかもしれないRailsのroutingの記述方をまとめてみた routeのmoduleとnamespaceとscopeの違い Railsのroutingにおけるscope / namespace / module の違い きゃまなかのブログ 【Ruby on Rails】ルーティング scope と namespace の違い RESTfulにするためRailsのルーティングをresources,namespace,scopeだけで頑張る Rubyの名前空間(namespace)について現役エンジニアが解説【初心者向け】 REST API利用時のNamespaceの重要性(RESTとGraphQLの比較とかも) Web API: The Good Partsを読んだまとめ Web API: The Good Partsを読んだので「設計変更しやすいWeb API」についてまとめた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails APIのルーティングnamespaceってなんで使うの?

はじめに Vue.jsをRailsで使うときにバックエンドをRailsのAPIモードで作り、 フロントエンドをVue.jsで作る記事をよく見かけた。 その際にルーティングでnamespaceを使っていたけれど なぜnamespaceを使うのかよくわからず、苦手意識があったので理解するため、まとめてみました。 まずはAPIとはそもそもなんぞやというところからはじめてみましょう。 対象読者 Railsを勉強してたけど、APIモードで課題を提出しなきゃいけなくなった方 Vue.jsなどフロントエンドも勉強している方 APIとは APIはApplication Programming Interfaceの略です。 ソフトウェアの機能を共有できる仕組みのこと。よく使われているものだとGoogle Mapなど。 郵便番号を入れると自動で入力されるなんてことができるのもこれのおかげだったり。 APIは通常Webに公開されていて、誰でも無料で使うことが可能。「WebAPI」と呼ばれたりもします。 一般的にJSONという形式で結果を返します。 RailsのAPIモードとは RailsのAPIモードはそのAPIをRailsで作成できるAPI作成に特化したモードのこと。 APIモードではMVCのViewg作成されません。 そのため、sass-railsやwebpacker、capybabaraなどはGemfaileには生成されません。 Rails4まではrails-apiというgemを入れる必要があったみたいですが 現在のバージョンでは特に何もしなくても使えます。 rails new アプリケーション名 --api と打つだけでAPIモードのRailsアプリケーションが作成されます。 次にそもそもnamespaceってなにという疑問を解消していきます。 Railsのルーティング RailsのルーティングはMVCモデルの基本の基本と言えるもので Viewから送られたリクエストを適切なコントローラーに送り、どんなアクションを行うかを管理するものです。 ルーティングはRailsアプリケーションのconfigディレクトリの中にあるroutes.rbに記述します。 Railsルーティング種類は調べてみるとたくさんありました。 urlを直接指定する root resouce resouces collection member new param shallow namespace scope concern constraints などなどたくさんあります。深そうですね。。。 scopeとnamespaceの違い ルーティングのまとめは別の機会にするとして 今回はその中でnamespaceにフォーカスを当てていきますが、 namespaceと似たようなscopeとの比較してみます。 scope namespace URL 指定のパス          指定のパス コントローラ   通常のcontroller内    controllerの中の指定のフォルダ scopeもnamespaceもURLを指定のパスにできますが namespaceはファイル構成も変えたい場合にいいみたいです。 scopeでもいいような気もしますね。 APIのバージョン railsのAPIを調べているとnamespaceを使ったroutes.rbの Rails.application.routes.draw do namespace 'api' do namespace 'v1' do resources :posts end end end などのところにあるv1という記述。 調べてみるとバージョン1の意味でした。 バージョン管理をするためにscopeではなく、namespaceを使っているのかとAPIのバージョン管理とは なんぞやと調べていきます。 Web APIのバージョン管理の重要性 Web APIとはアプリケーションのインターフェイスの役割を持ち、追加、変更、廃止などされていくものです。 通常のアプリもver.1.0.8とか書かれていますよね。 セマンティックバージョニングと言います。 バージョン管理を特にせず、管理者がこっちの方がいいから変更しよう〜とAPIを書き換えてしまったら そのAPIを使っているユーザーがいきなり使えなくなってしまう可能性があります。 例えばFacebookやGoogleなどのAPIが急に変更されると エラーが出て処理が止まったり、表示がおかしくなるなどの不具合が発生します。 それを防ぐために公開されているAPIは複数のバージョンを提供して、 そういう事態を招くことを防いでいるわけです。 APIのURI一覧 DMMのAPI https://api.dmm.com/affiliate/v3/ItemList?api_id=[APIID]&affiliate_id=[アフィリエトID]&site=DMM.R18&service=digital&floor=videoa&hits=[検索数]&sort=date&keyword=[キーワード]&output=[jsonかxml] TwitterのAPI https://api.twitter.com/2/tweets/search?tweet.fields=created_at,author_id,lang&query=$QUERY" YouTubeのAPI https://developers.google.com/youtube/v3/docs/ FacebookのAPI https://graph.facebook.com/v2.0/me とURIの中を見てみると、v○とあります。 いくつかバージョンの管理方法があるようなのですが URIにバージョンを埋め込むのがよく利用される方法のようです。 まとめ これらから考えられることはWeb APIは一人のユーザーが利用するものでなく、 アプリケーションと同様に多くの人が利用するために作られるためバージョン管理がされている。 その慣例としてv1などのバージョンをつけてルーティングをつけている。 それを実現するにはscopeよりもnamespaceが良いため、namespaceでルーティングをしていることが考えられる。 終わりに RailsでAPIを作るとなったときに 知らないnamespaceなどが出てきてよくわからなくて混乱しましたが なぜそうしているのかを時間はかかりますが紐解くのは大事です。 さまざまな記事を読ませていただいたのですが、それ違うなどもあると思いますので ぜひご指摘いただけたら嬉しいです。 参考サイト Railsのルーティングの種類と要点まとめ 初心者じゃなくても役に立つかもしれないRailsのroutingの記述方をまとめてみた routeのmoduleとnamespaceとscopeの違い Railsのroutingにおけるscope / namespace / module の違い きゃまなかのブログ 【Ruby on Rails】ルーティング scope と namespace の違い RESTfulにするためRailsのルーティングをresources,namespace,scopeだけで頑張る Rubyの名前空間(namespace)について現役エンジニアが解説【初心者向け】 REST API利用時のNamespaceの重要性(RESTとGraphQLの比較とかも) Web API: The Good Partsを読んだまとめ Web API: The Good Partsを読んだので「設計変更しやすいWeb API」についてまとめた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

バリデーションをまとめる方法

はじめに アウトプット用に書かせて頂きます。 ユーザー管理機能を実装するためにuserテーブルにバリデーションをかけ、コードレビューをして頂いた回答で同じバリデーションをかけるときはまとめる事ができるという事を知りました。 with_options do 下記の記述でまとめる事ができます。 with_options do #記述 end ではまずwith_optionsを使わないコードを記述します。 user.rb class User < ApplicationRecord validates :nickname, presence: true validates :birth_day, presence: true validates :first_name, presence: true validates :last_name, presence: true validates :first_name_kana, presence: true validates :last_name_kana, presence: true end #presence trueとは空では登録できないようにするバリデーション 全てprecence: trueと同じバリデーションをかけているのでひとまとめにします。 user.rb class User < ApplicationRecord with_options presence: true do validates :nickname validates :birth_day validates :first_name validates :last_name validates :first_name_kana validates :last_name_kana end end これでひとまとめにする事ができます。 しかしprecence true以外にもバリデーションをする時が多いと思います。 user.rb class User < ApplicationRecord validates :nickname, presence: true validates :birth_day, presence: true validates :family_name, presence: true, format: { with: /\A[ぁ-んァ-ヶ一-龥々]/ } validates :first_name presence: true, format: { with: /\A[ぁ-んァ-ヶ一-龥々]/ } validates :family_name_kana, presence: true, format: {with: /\A[\p{katakana} ー-&&[^ -~。-゚]]+\z/ } validates :first_name_kana, presence: true, format: {with: /\A[\p{katakana} ー-&&[^ -~。-゚]]+\z/ } end 上記の記述で下記の正規表現を使いました。 正規表現 意味 /\A[ぁ-んァ-ヶ一-龥々]/ 全角ひらがな、全角カタカナ、漢字 /\A[\p{katakana} ー-&&[^ -~。-゚]]+\z/ 全角カタカナ     このような時にwith_optionsの中にwith_optionsを入れ子のようにする事ができます。 user.rb class User < ApplicationRecord #全行にpresence: trueをする with_options presence: true do validates :nickname validates :birth_day #この2行だけformat: { with: /\A[ぁ-んァ-ヶ一-龥々]/ } with_options format: { with: /\A[ぁ-んァ-ヶ一-龥々]/ } do validates :family_name validates :first_name end #この2行だけ {with: /\A[\p{katakana} ー-&&[^ -~。-゚]]+\z/ } with_options format: {with: /\A[\p{katakana} ー-&&[^ -~。-゚]]+\z/ } do validates :family_name_kana validates :first_name_kana end end end 以上です。     
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Amazon SESの署名バージョン4に対応させる

はじめに RailsでAmazon SESの署名バージョンを3から4に対応させたときの備忘録です。 SESのライブラリはgem 'aws-ses'を使っていました。 人によってファイルの設定やリージョンなどは異なるので、あくまで参考程度にしてください。 環境 Rails 6.0.3.7 ruby 2.6.5 MacOS gem 'aws-ses', '~> 0.6' エラー内容 FATAL -- : AWS::SES::ResponseError (InvalidClientTokenId - Signature Version 3 requests are deprecated from March 1, 2021. From that date on, we are progressively rejecting such requests. To resolve the issue you must migrate to Signature Version 4. If you are self-signing your requests, refer to the documentation for Authenticating requests to the Amazon SES API [1] with Signature Version 4 [2]. If you are not self-signing your requests, simply update your SDK/CLI to the latest version. [1] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-authentication.html [2] https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html): google翻訳 致命的-: AWS :: SES :: ResponseError(InvalidClientTokenId-署名バージョン3のリクエストは2021年3月1日から非推奨になりました。その日以降、このようなリクエストは段階的に拒否されます。問題を解決するには、署名バージョン4に移行する必要があります。 -リクエストに署名するには、署名バージョン4 [2]を使用したAmazonSES API [1]へのリクエストの認証に関するドキュメントを参照してください。リクエストに自己署名しない場合は、SDK / CLIを最新バージョンに更新してください。[ 1] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-authentication.html [2] https://docs.aws.amazon.com/general/latest/gr/ sigv4-create-canonical-request.html): エラーの内容通り、署名バージョンを4に移行させる必要があるそうです。 やったこと gem 'aws-ses', '~> 0.6'を gem aws-ses-v4に変えた。 aws-sesのissuesをみると、バージョン4に移行することについて結構多くの人が話していました。 gem aws-ses-v4はgem 'aws-ses'を署名バージョン4に対応させたgemです。 他にもAWSが推奨しているaws-sdk-railsというGemがあるそうですが、そちらに移行させる時間はなさそうだったので今回はaws-ses-v4を使うことにしました。 できれば公式が推奨している方を使うべきだと思います。 Gemを変更 Gemfile - gem 'aws-ses', '~> 0.6' + gem "aws-ses-v4", require: "aws/ses" $ bundle install aws.rbの変更 ここら辺は人によって違うかもしれません。 各々のメールの設定に合わせてください。 ちなみに私は最終的に以下のようになりました。 config/initializers/aws.rb ActionMailer::Base.add_delivery_method :ses, AWS::SES::Base, access_key_id: Rails.application.credentials.aws_ses_access_key_id, secret_access_key: Rails.application.credentials.aws_ses_secret_access_key, server: 'email.リージョン名.amazonaws.com', #人によって違います region: 'リージョン名' #SESのリージョンを指定。 例:us-east-2 以下のエラーが出た時はSESのリージョンが間違っている可能性があります。 SignatureDoesNotMatch - Credential should be scoped to a valid region, not 'ap-northeast-1' また、awsのアクセスキーなどを記載するcredentials.yml.encには、以下のコマンドで確認・編集できます。 EDITOR=vim rails credentials:edit 以上です。 参考 aws-ses GitHub aws-ses-v4 GitHub 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DiscordのBotを作ってみよう①準備編

はじめに 初めまして!とみーといいます。初めての記事執筆します。よろしくお願いします。 筆者自身、プログラミング初心者で、間違った解釈等が記事にあるかもしれません。ご了承ください。 以前、練習で少しだけ開発したことがあったのですが、久しぶりに思い出しました。 初めて、RubyでDiscordのBotを作成してみたいかた向けに開発のヒントにしていただければと思い、今回の記事を書くことにしました。 この記事の目的 Botを自分で作ってみたいと思っているかたの開発のヒント、助けになればと思い記事を作成することにしました。 ある程度のBotが作成できるようになることを目的にしています。 ご興味がありましたらぜひ最後までご覧ください! 自分の開発環境について 記事を書く前に自分の開発環境について紹介したいと思います。 使っているPC OS Windows10 使用しているエディタ Visual Studio Code(VS Code) Rubyのバージョン Ruby 2.7.2 Discordrbのバージョン discordrb 3.4.0 ※どのOSでもRuby開発環境がそろっていれば開発可能です。 エディタは筆者はVisual Studio Code を使っていますが、これにこだわる必要はありません。 もし、自分のお気に入りのエディタ、好きなエディタがある場合は、それを使っていただければ良いかと思います。 Rubyは執筆当時はRuby 3.0.0がありますが、筆者は2.7.xで開発しています。 注意すること Windowsでユーザ名を日本語で作成されている方向けですが、日本語のユーザ名にしている場合はこの先のインストールがうまくいかない可能性があります。 インストール中、ここに書いていない情報や、エラーが出てくる可能性もあります。その際は、エラー文などを読んで、調べてみてください。 インストールには時間がかかります。時間に余裕があるときにインストールすることをおすすめします。 バージョンはインストールする時期によって、記事よりも新しいバージョンになっている可能性があります。その際は読み替えて、この先を読み進めてください。 開発環境をそろえてみよう! エディタ コード(プログラム)を書くためのエディタです。 メモ帳でもできないことはないですが、エディタにはシンタックスハイライト(プログラムしたら、文字に色ついて教えてくれるもの)などプログラムに便利な機能があるため、こちらはほぼ必須かと思います。 筆者は上記の通りVisual Studio Codeを使っています。 他にAtomやNotepad++などがあります。 お好みのエディタを使ってください。 Rubyのインストール 次にRubyのインストールをしていきましょう。 Windowsにインストール インストールはこちらの記事が参考になります。 上記記事はRuby on Railsのインストールについて説明されていますが、その中のRubyインストールのみしていただければ大丈夫です。 Macにインストール Mac osをお使いの方はこちらの記事が参考になります。 ※macはHomebrewも必要になります。 discordrbをインストールしよう! 次にBotを作るために必要なGem、discordrbをインストールしましょう。 Windowsはコマンドプロンプト、macはターミナルを開いてください。 Windows コマンドプロンプト > gem install discordrb --platform=ruby >は入力不要です。gemから入力してください。 Windowsは後ろに --platform=rubyを付けないといけないみたいです。 Mac ターミナル $ gem install discordrb $は入力不要です。gemから入力してください。 インストールできているか確認 コマンドプロンプト・ターミナル gem list # gem listと入力して、discordrb出てればOK! *** LOCAL GEMS *** discordrb (3.4.0) discordrb-webhooks (3.3.0) ... 以上で開発環境はそろいました。次に、Botを作成しましょう。 Botを新規作成する 次はDiscord Developer PortalでBotを作成していきましょう。 ※Discordのアカウントが必要になります。この記事を読まれているということはおそらく持たれていると思いますが、まだの方は、あらかじめ作成しておいてください。 1. New Applicationで追加 New Applicationをクリック 2. 名前の入力 Nameに任意の名前(Botの名前にもなります。) 入力したらCreateをクリック 3. プロフィール画像の設定(任意、後からでもできます。) APP ICONのところに画像を設定すると、Botのプロフィール画像になります。 Application ID(橙色の枠)は後程使用します。 次にBotをクリック 4. Botの新規作成 Add Bot→Yes do it!をクリック 5. Botの設定 USER NAMEに先ほど設定した名前が登録されています。 ※Botの名前を変更したい場合はここを変更します。 TOKEN(橙色の枠)は後程使用します。 ※TokenはBotにログインするために必要な他人に知られてはいけない重要なコードです!大切に保管してください。 次に、OAuth2をクリック 6. Bot導入リンクの作成 まず、Botにチェック 7. Botに与える権限の設定 Bot PermissionsはBotに与える権限です。 必要な権限にチェックをつけましょう。 ※今回の記事ではメッセージ関係、VC関係しか使わないと思います。 全て完了したら、上のURLのCopyをクリックして、ブラウザの新しいタブに貼り付けてください。 Botを導入できます。 ※自分が(Discordの)"サーバの管理"の権限を有している必要があります。 ない場合は、(Discordの)新しいサーバを作成して、そこで追加するか、管理人様に権限をお願いしてみてください。 以上で、導入完了です! 今回やったこと Rubyのインストール discordrbのインストール Botの新規作成 Botのサーバへの追加 おわりに ここまで導入お疲れさまでした。Rubyからインストールした方は非常に大変だったかと思います。自分も導入は結構手間取った覚えがあります。 特に自分はwindowsのユーザ名が日本語のため、うまく通らず、ユーザを新規作成して導入しました。やっぱり、ユーザ名は最初から日本語で作らないほうがいいね(笑) ここまで見てくださった皆様、本当にありがとうございました。 次回より、Botを作っていきたいと思います。よろしくお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

attr_accessorとは

この記事の対象者 railsはある程度経験がある(railsチュートリアルを完走した人) rubyでアクセサメソッドの使用経験のない人 記事の要約 attr_accessorはインスタンス内の属性を変更したり、参照する際に必要なメソッド 検索クエリなどのDBに保存する必要のないモデルを使用する際に使う。検索機能などはどんなwebサービスでも使用されることが多いため、この辺の理解はしっかりしておく必要がある。 attr_accessorとは rubyで使用されるアクセサメソッドのことを指します。 そもそもアクセサメソッドとは? アクセサとは、オブジェクト指向プログラミングで、オブジェクト内部のメンバ変数(属性、プロパティ)に外部からアクセスするために用意されたメソッド。メンバ変数をオブジェクト内部に隠蔽し、外部から直接参照させないようにするために用意される。 参考記事 これはどういうことかと言うと、「クラスから作られたインスタンス内の属性を変更したり、呼び出したりするために必要なメソッド」ということです。 具体例 ここまで文章だけ読んでもピンとこないと思うので、ここからは具体例を用いて説明したいと思います。 Userの名前を管理するモデルを作っていると仮定します。 user.rb class User def initialize(name) @name = name end end ここで試しにuser = User.new(name: '佐藤')と入力してみます。 すると以下のようなオブジェクトが返ってきます。 #<User:0x00007feb6aa43820 @name='佐藤'> ここでインスタンス内のname属性の値を呼び出してみたいと思います。 user = User.new(name: '佐藤') user.@name SyntaxError: unexpected tIVAR user.@name    ^~~~~ インスタンス変数はクラスの外部から参照できないので、エラーが出てしまいましたね。 railsを使った経験のある方ならなんとなくイメージできるかと思いますが、インスタンス内の属性を参照するにはuser.nameと書く必要があります。 user = User.new(name: '佐藤') user.name NoMethodError: undefined method `name' for #<User:0x00007fcee585d520 @name="佐藤"> nameメソッドがないとエラー文で言われているので、nameメソッドを定義する必要があります。 user.rb class User def initialize @name = name end  def name @name end end user = User.new(name: '佐藤') user.name => '佐藤' と出力されたと思います。 今度は佐藤さんではなくて、田中さんに名前を書き換えたいとします。 user = User.new(name: '佐藤') user.name = '田中' NoMethodError: undefined method `name=' for #<User:0x00007fcee585d520 @name="佐藤"> name=というメソッドがないよと言われてますね。 ですので今後は以下のようにuser.rbを書き直していきます。 user.rb class User def initialize @name = name end  def name @name end def name=(value) @name = value end end user = User.new(name: '佐藤') user.name = '田中' => "田中" user.name => '田中' ちゃんと書き変わりましたね。このように、インスタンス内の値を書き換えたり、参照するには以下のようにメソッドを定義してあげる必要があります。しかし、属性が少ないならこれでも良いかもしれませんが、属性が多くなってくるとコードが長くなってしまいますね。 そこで、Rubyではアクセサメソッドというものがあり、先ほどのuser.rbをもっと簡単に書き換えることができます。 class User attr_accessor :name def initialize @name = name end end こう書くだけでUserモデルのインスタンス内のname属性を参照・変更することが出来ます。 こっちの方が記述量も少なくスマートですよね。 他にも参照だけしたい場合はattr_reader、変更だけしたい場合にはattr_writerというアクセサメソッドが存在するので、その時に応じて使い分けましょう。 これってどんな時に使うの? ここまで読んでいただいて、「使い方はわかったけどどんな時に使うの? そもそもrailsでアプリ作った時にこんなの使わなかったよ」と思う方もいらっしゃると思います。ですので、どんな時に使うかも説明します。 DBにデータを保存する必要がないモデル(例えば検索機能の検索パラメータなど)を作成するときに使用します。 通常DBに保存する場合には、railsのApplicationRecordというクラスを継承しているため、アクセサメソッドを定義しなくてもuser.nameと書くだけで、インスタンス内の属性を読み込めてしまいます。しかし、DBにデータを保存しない場合は、自分でアクセサメソッドを定義する必要があります。(実務で実際にやりました。) 最後に アクセサメソッドに関しては、プログラミング学習を始めた初期に見たことがありましたが、正直全く覚えていませんでした。しかし、実務に入って結構使うことが多いと感じたのでこれから転職活動を始められる方はその辺の理解もしっかりしておくことが重要だと感じました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む