ActiveSupport::Concernとは?
ActiveSupport::Concernとは ?
ActiveSupport::Concernを使うことで、複数のcontrollerで利用する処理をモジュール化することができます。
モジュールを作成する
app/controllers/concerns
にモジュールを設置します。
# モジュール名はキャメルケースです module HogeHoge # 以下は共通モジュールを使用するための記述を肩代わりしてくれるモジュールです # モジュール内がインスタンスメソッドの定義だけであれば省略可能です extend ActiveSupport::Concern def fugafuga # fugafugaメソッドはcontrollerからコールできます end private def foo # fooメソッドはモジュール内からのみコールできます end end
モジュールをcontrollerからコールする
class TestController < ApplicationController # 利用したいモジュールを事前にinclude include HogeHoge def action # 事前にHogeHogeモジュールをincludeしているため、fugafugaメソッドがコール可能 fugafuga end end
includedブロック
module HogeHoge extend ActiveSupport::Concern included do # HogeHogeモジュールがincludeされた後に、このブロックが実行される # 主にscope, collback等を記述する end def fugafuga end private def foo end end
このようにActiveSupport::Concernを利用することで、DRYなコードを記述することができます。
helperメソッドを使ってみる
Helperとは?
viewをDRYに記述することができるモジュールです。Helperを利用することでviewファイルの可読性が向上します。
helperはlink_to
やform_tag
などのメソッドをデフォルトで用意してくれていますが、独自に作成することも可能です。
helperメソッドを定義してみる
今回は例として、questionsテーブルのis_resolutionカラムがtrueであれば解決
、falseであれば未解決
と表示する、helperメソッドを定義します。
# view側で`resolution_text`という、helperメソッドを呼び出します。 <%= resolution_text(@question) %>
module QuestionsHelper def resolution_text(question) if question.is_resolution? '解決' else '未解決' end end end
このようにhelperメソッドに処理を切り出すことで、viewをDRYに記述することができます。
letter_openerを使ってみる
letter_openerとは?
開発中のアプリケーションから送信されたメールを、ブラウザ上で簡単に確認することができるGemです。
今回は前提条件としてデバイスをインストールし、メール認証の設定が完了していることを前提としています。
letter_openerをインストール
group :development do gem 'letter_opener' end
$ bundle install
設定ファイルを修正する
config/environments/development.rb
に以下のコードを追記します。
config.action_mailer.delivery_method = :letter_opener
Devise認証メールを送ってみる
ブラウザで以下のような画面(文章等は自分でカスタマイズできます。)が表示され、メール内容を確認することができます。
このようにletter_opnerを使うことで、簡単にメールを確認することができます。
Rails Adminを使ってみる
RailsAdminとは?
アプリケーションの管理画面を自動生成してくれるgemです。
管理画面内でデータの確認や追加ができるようになります。
今回は前提条件として土台のrailsアプリケーションとdeviseのセットアップは完了していることを想定しています。
RailsAdminをインストール
gem `rails_admin`
$ bundle install
RailsAdminの設定ファイルを作成
$ rails g rails_admin:install
このコマンドを実行すると、「管理画面のパスは何にする?」みたいなことを聞いてくるのでadmin
と入力し実行します。
するとroutes.rb
に以下のコードが自動生成され、
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
config/initializers/rails_admin.rb
ファイルが生成されます。
ブラウザで確認してみる
ブラウザhttp://localhost:3000/admin
にアクセスし、admin画面が追加されているか確認してみます。(以下の写真はイメージです。当たり前ですが、モデル名などはアプリケーションごとに異なります。)
現状、全ユーザーが管理画面へアクセス出来てしまうので、アクセス権限を持つユーザーのみアクセスできるようにします。
admin画面のアクセス制御
アクセス制御はcancan
というgemを使って権限管理します。
gem 'cancan'
$ bundle install
config/initializers/rails_admin.rb
の以下のコードをコメントアウトします。
コメントアウトすることでrails_adminをdeviseとcancanに連携することができます。
# == Devise == config.authenticate_with do warden.authenticate! scope: :user end config.current_user_method(&:current_user) # == Cancan == config.authorize_with :cancan
再度http://localhost:3000/admin
にアクセスし、制御が出来ているかを確認します。
次にusersテーブルにadminカラムを追加します。
$ rails g migration AddColumnAdminToUser admin:boolean
class AddColumnAdminToUser < ActiveRecord::Migration[5.0] def change add_column :users, :admin, :boolean, default: :false end end
app/models/ability.rb
のinitializeメソッド内に、制御ロジックを追記します。
def initialize(user) if user && user.admin? can :access, :rails_admin can :manage, :all end end
ここまでの作業を終えると、usersテーブルのadminカラムの真偽値によるアクセス制御をかけることが出来ます。
gonを使って、railsの変数をJSに渡す
gonとは?
Railsアプリケーション側で定義した変数をJSに渡すためのGemです。
gonをインストール
gem `gon`
$ bundle install
gonをincludeする
app/views/layouts/application.html.erb
に以下のコードを追記します。
<%= include_gon %>
controllerでRailsの変数をJSで使える変数に渡す
gon.hoge = "ほげほげ"
このようにgon.変数名
とすることで、JS側で利用できる変数を定義することができます。
ブラウザで変数を確認
chrome検証画面のコンソールからconsole.log(gon.hoge)
で確認してみましょ
find_or_create_byを使ってみる
find_or_create_byとは
検索条件に合致するデータが存在した場合、1件目のデータを取得し、存在しない場合は新規作成します。
$ モデル名.find_or_create_by(条件)
アプリケーションの土台を作る
$ rails new find_or_create_by_test
$ rails g scaffold User name:string
$ bin/rails db:migrate
find_or_create_byを使って、データを作成する
以下のコードは、name: "Taro"
のデータが存在すれば取得、
存在しなければブロックを実行し、データを作成します(今回はこっち)。
User.find_or_create_by(name: "Taro") do |user| user.name = "Taro" end
name: "Taro"
のデータ作成されました。
find_or_create_byを使って、データを取得する
user = User.find_or_create_by(name: "Taro") do |user| user.name = "Taro" end
既にname: "Taro"
のデータは存在するので、今回はデータの取得のみになります。