Morizou on Rails

行動・努力・俯瞰

新しい学び 18日目

学び

rakeタスク
rubyで書くことができるタスクで、これをまとめておくことで必要に応じて呼び出すことができる。
$ rails g task 〇〇でrakeタスクファイルを作成。
EX.
$ rails g task helloを作成したら、lib/tasks/hello.rakeというファイルが作成される。
そして中身を
lib/tasks/hello.rake

namespace :hello do
  desc 'thankyou'
  task goodbye: :environment do
     〜実行する内容〜
  end
end

のように書く。そして$ bundle exec rake -Tをすると、使用できるrakeコマンドが一覧でてくるので、その中に

rake hello:goodbye # thankyou

と作成したものが存在すれば使用可能になる!
Wheneverを設定するときには必要不可欠。

cron
cronとはバックアップとかログのローテートとかみたいに定期的に自動的に実行したいシステムを管理・実行するもの。デーモンプロセスの一種。
デーモンプロセス? => 利用者の操作とは無関係にバックグラウンドで処理をしてくれるプロセスのこと。
cronはcrontabという定期的に実行するために必要な情報を載せるファイルに設定をして使用できるようになる。
ただこれを設定するのはなかなか難解なので、そういった際にrubyの形式で記述してこのcrontabに情報を反映させてくれるWheneverというgemが役に立つ。

Whenever
gem 'whenever', require: falseで導入。
$ bundle exec wheneverize .でconfig/schedule.rbが作成される。
config/schedule.rbは通常のrubyの書き方で書くことができる。 $ bundle exec whenever —update-crontabをすることでconfig/schedule.rbの内容をcronの構文に変換して、crontabに設定を反映させることができる!
config/schedule.rbの書き方に関しては学び中。

参考URL

https://qiita.com/yoshito410kam/items/26c3c6e519d4990ed739
https://railsdoc.com/page/find_each
https://opiyotan.hatenablog.com/entry/rails-rake-task
https://www.express.nec.co.jp/linux/distributions/knowledge/system/crond.html https://e-words.jp/w/%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3.html#:~:text=%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3%20%E3%80%90daemon%E3%80%91%20%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9&text=%E5%88%A9%E7%94%A8%E8%80%85%E3%81%AE%E6%93%8D%E4%BD%9C%E3%81%A8,%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%9F%E3%82%8A%E3%81%99%E3%82%8B%E3%80%82 https://github.com/javan/whenever

新しい学び 17日目

学び

with_options
modelにおいて共通のバリデーションをつけたい際に使用できる。
EX.
**app/models/user.rb

with_options presence: true do
  validates :name
  validates :email
  validates :password
end

とような感じで使用可能。
また、with_optionsなのでその他のオプションの事項もまとめられる。
EX.

with_options if: :admin? do
  validates :name, presence: true
end

〇〇was・〇〇changed?
〇〇にはカラム名が入る。Railsのメソッドであり、〇〇_wasは元の状態に戻す方法、〇〇_changed?は状態が前と比較して変わったかを確認する方法。
EX.
Postモデルのreleaseカラムが存在し、フォームで登録をする前のカラムの状態はpreparationで、createアクションで登録をしたらカラムの状態をshowingにするためにアクションの中にpost.release = showingが実行されるとする。
その際にフォームの記入ミス等でレンダリングする場合、上記のように代入している場合をもとの状態にもどしたいときに

post.release_was if post.release_changed?

みたいに書けば、releaseの状態がshowingに変わっていた時は元のpreparationの状態に戻すことができる。

ただこれは現在は推奨されておらず、代わりにattribute_in_databaseとかhas_changes_to_save?を使用することが推奨されている。

参考URL

https://qiita.com/TerToEer_sho/items/2b2c36b615d92b7dd021

https://morizyun.github.io/ruby/active-record-attribute-was-change.html

https://qiita.com/htz/items/56798d53ec5988733fc6

新しい学び 16日目

学び

shared_examples_for
RSpecにおいて、共通化をするために使用。たとえば下の例だとshared_examples_for 'A' doで定義したit 'B' doの内容は、it_behaves_like 'A'で丸々その内容を貼り付けることができる。

shared_examples_for 'A' do
  it 'B' do
  〜内容〜
  end
end
〜
describe 'C' do
    context 'D' do
       it_behaves_like 'A'

そのためit内で部分的に使用したい場合はこの共通化方法をとるのは不適切で、その場合はbefore doを使用したりする方がいい。

SecureRandom.uuid
SecureRandomはセキュリティ的安全でランダムな文字列を作成。uuidはUniversally Unique IDentifierの略で、SecureRandomのオブジェクトとして使用される。

参考URL

https://qiita.com/jnchito/items/42193d066bd61c740612
http://www.code-magagine.com/?p=7773

https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html#S_UUID

エスケープ回避

エスケープとは?

エスケープ処理とは、プログラミング言語やソフトウェアで文字列を扱う際に、特定の記号文字などに続けて記された文字(の並び)に、その文字本来の意味とは異なる特別な意味や機能を与えること。先頭の特殊な文字を「エスケープ文字」という。

Rails3以降<%= '〇〇' %>を使って出力を行う場合、HTML特殊文字は自動的にエスケープされるようになっているため、文字をありのまま出力したい場合でもエスケープをしてしまう可能性がある。

エスケープを回避するための手段として'〇〇'.html_safesanitize '〇〇'がある。

'〇〇'.html_safe

これを使用することによって、エスケープをせずそのままの文字列を表示できる。
ただ悪意のあるコードなどもそのまま表示してしまうため、安全性はイマイチ。

sanitize '〇〇'

こちらも同様エスケープをせずそのままの文字列を表示できるが、XSS対策もしてくれることによって(XSSとは動的なHTMLを読み込む際に悪意のあるコードが紛れ込んでしまうこと)、悪意のあるコードについてはエスケープされる。

どっちを使う?

なので、システム上であらかじめ準備してある文字列を表示する場合は'〇〇'.html_safe、アプリケーションを使用するユーザが入力したデータを表示する際にはsanitize '〇〇'を使用すればいいと思われる。

参考URL

https://e-words.jp/w/%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E5%87%A6%E7%90%86.html
https://www.javadrive.jp/rails/template/index7.html
https://www.y-hakopro.com/entry/2020/01/01/html_safe%E3%81%A8sanitize%E3%81%AE%E9%81%95%E3%81%84
https://qiita.com/kamohicokamo/items/571c58f2d6738a7dfe6a

新しい学び 15日目

学び

transaction
controller内でごっちゃにならないように情報の生合成を保つために使用する。
User.transaction doだと、Userに合わせた感じでまとめられる。

dig
h.dig(:foo, :bar, :baz)みたいな感じで使うのだが、例えば要素のどれかがnilだった場合はnilを返す。要素に問題がなければそのまま返す。なので要素にnilがありそうなときに弾くために使うと便利。

whereの条件比較
User.where("id > ?", 1)でidが1以上のuserを探してくれる。第一引数は""''で囲わないといけない。

reload
javascriptで一部のページだけ読み込むために使用。Ajaxでよく利用する。

sanitize
XSS対策をしつつエスケープを回避してくれるメソッド。XSSとは動的なHTMLを読み込む際に悪意のあるコードが紛れ込んでしまうこと。sanitize "〇〇"のように使う。

参考URL

https://railsdoc.com/page/transaction

https://docs.ruby-lang.org/ja/latest/method/Hash/i/dig.html

https://pikawaka.com/rails/where

https://www.sejuku.net/blog/25316

https://www.y-hakopro.com/entry/2020/01/01/html_safe%E3%81%A8sanitize%E3%81%AE%E9%81%95%E3%81%84

https://qiita.com/kamohicokamo/items/571c58f2d6738a7dfe6a

新しい学び 14日目

学び

JavaScript
対象要素.on( イベント名, セレクタ, データ ,関数 )
イベント名をclickセレクタ'.js-select'とした場合、.js-selectでが与えられたクラスの箇所をクリックすると、指定した関数が実行されるという感じ。

modal
Bootstrapで使用可能。ライトボックス, 通知, カスタムダイアログを作成できる。
data-toggle = "modal"をスイッチとし、data-target= 〇〇でidを指定して、そのidが付与された部分がmodalウインドウとして呼び出される。

参考URL

https://www.sejuku.net/blog/38774

https://qiita.com/takachan_coding/items/9179cf361d0e92ae0bad

https://getbootstrap.jp/docs/4.2/components/modal/

Pundit

調べてもあまり詳しい情報が載ってなかったので少し自信がないので、間違えがあったら随時更新しようと思います。

設定方法と概要

punditは認可の仕組みを提供する。
gem ‘pundit’によって導入。 $ rails g pundit:installでapp/policiesフォルダが作成され、その中にapplication_policy.rbファイルが作成される。基本的には各controllerに対応して個別のpolicyファイルを作る。
その設定を作成したapp/policies以下にあるporicyファイルで細かく定義をすることができる。基本的にapp/controllers/application_controller.rbにinclude Punditを記述すればporicyファイルに記述した条件で認可を行うことができる。
実際に機能を使用するには、controllerの各アクションでauthorize リソースオブジェクトをすると対象のリソースに対して権限があるかを確認してくれる。

使用例

$ rails g pundit:installをすると
app/policies/application_policy.rb

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end
end

が作成される。このuserはcurrent_userがデフォルトでセットされるらしい。
またrecordについてはgemのREADME曰く、これはデフォルトで設定してあるだけで、なんでもいいらしい。
そしてそのapplication_policy.rbまたは、それを継承している例えばcomment_policy.rbみたいなものの中で
app/policies/comment_policy.rb

class CommentPolicy < ApplicationPolicy
  def update?
    user.admin? or not record.published?
  end
end

このようにcontrollerのアクション名+?のメソッドを定義し、返り値がtrueなら許可、falseなら拒否というようになる。(中身を単にtrueかfalseにしてもOK)
そして該当controller内で
app/controllers/admin/comments_controller.rb

def update
  @comment = Comment.find(params[:id])
  authorize @comment
  if @comment.update(comment_params)
    redirect_to @comment
  else
    render :edit
  end

end

のようにauthorize @commentとすることで@commentを使用する権限があるかを確認する。その確認方法としてとられるのが先ほどapp/policies/comment_policy.rbで設定したupdate?内のuser.admin? or not record.published?。これが通れば許可され、正常にupdateアクションが実行される。
逆に権限がなければ拒否をされ、elseとなり編集画面にレンダリングされる。
こんな感じで、実際のアプリケーションでは条件分岐で使うことが多いらしい。

参考URL

https://github.com/varvet/pundit
https://qiita.com/zaru/items/8bf7b41b33f3f55bd27d
http://www.code-magagine.com/?p=12027