この記事は Rails管理画面gem の新星!administrate を使おう その3です。
関連記事はこちら
- Rails管理画面gem の新星!administrate を使おう - その0 紹介 - Qiita
- Rails管理画面gem の新星!administrate を使おう - その1 導入 - Qiita
- Rails管理画面gem の新星!administrate を使おう - その2 基本カスタマイズ - Qiita
- この記事
- [TBD] Rails管理画面gem の新星!administrate を使おう - その4 もっとカスタマイズ!
他のgemと連携
おなじみの有名gemと連携してみます。
(ここでは有名gemは利用可能な状態で記載していきます)
連携お相手のgemのことがちゃんとわかってればサクッとできる。
(わかってなかったので苦戦・・)
- 認証 : devise
- タグ付け:act_as_taggable_on
- 画像アップロード:paperclip
- ページネーション:kaminari
認証 : devise
Administrateには認証系の機能は一切ありません。
アプリケーションでお使いの認証機能をこちらにも使ってみます。
一番の有名どころであるDeviseとの連携は簡単!
準備
特になし。
Deviseは使える状態になってるものとします。
管理画面側修正
rails generate administrate:install
で生成された application_controller.rb
をちょこっと修正します。
module Admin
class ApplicationController < Administrate::ApplicationController
before_filter :authenticate_admin
def authenticate_admin
# TODO Add authentication logic here. ここここ!!
authenticate_user!
end
# Override this value to specify the number of elements to display at a time
# on index pages. Defaults to 20.
# def records_per_page
# params[:per_page] || 20
# end
end
end
authenticate_user!
は devise でおなじみのアレですね。
タグ付け:act_as_taggable_on
Administrate demoの顧客管理アプリケーションを例に拡張してみます。
準備
Product にタグをつけてみます。
class Product < ActiveRecord::Base
validates_presence_of :name, :price, :image_url
acts_as_taggable
acts_as_taggable_on :category
end
管理画面側修正
Dashboardから操作できるようにします。
イマイチなやり方
category_list
をStringで登録できるようにしてみます。
ATTRIBUTE_TYPES = {
# ...
category_list: Field::String,
}
COLLECTION_ATTRIBUTES = {
# ...
:category_list,
}
SHOW_PAGE_ATTRIBUTES = {
# ...
:category_list,
}
FORM_ATTRIBUTES = {
# ...
:category_list,
}
acts_as_taggable_on の登録の仕方から、 category_list にカンマ区切りで登録すると、無事タグとして登録できることがわかります。。
↓カテゴリの所、, も入力するとちゃんと3個のタグが付くの図
新規作成の場合。
登録できて、タグも3つ作られている。
よしよし・・・いや・・待て、全然よくない!
問題点
すでに作成されたProduct のupdateをしようとすると、
カテゴリにカンマなくなってる!
(editで戻ってきた時にすでにcategory_list登録済みの場合)
このまま登録してしまうと、game gift family
という残念な1個のタグになってしまいます;;
これはいかん・・なんとか form で表示するときにカンマ付きに戻しておきたい。
修正
カスタムフィールドを追加してみます。
> rails generate administrate:field string_tag
以下のファイルが生成
- app/fields/string_tag_field.rb
- app/views/fields/string_tag_field/_show.html.erb
- app/views/fields/string_tag_field/_index.html.erb
- app/views/fields/string_tag_field/_form.html.erb
微修正。。。
def joined
data.join(',')
end
<div class="field-unit__label">
<%= f.label field.attribute %>
</div>
<div class="field-unit__field">
<%= text_field_tag "#{f.object_name}[#{field.attribute}]", field.joined %>
</div>
これでデータが登録済みの場合は join(',')
してくれた文字列が表示されるように!
もうちょっとタグてきな見た目にするjsやcssと連携する方法までは力尽きて調べてません。。
(管理画面なので・・入力者多少頑張れ・・とか逃げてみる)
画像アップロード:Paperclip
その前に・・
本家のデモサイト では、プロダクトに画像が表示される状態になっています。
どうやって実現してるのか、ちょっと気になって調べてみました。
- Product モデルに image_url を string で保持しているだけ
- 画像を実際にアプリにアップロードせず、URLだけを保持
- Administrate の標準タグでついてくる
Field::Image
を使ってる
gem の中を見てどうやって実現してるのかチェック!
Field::Image
の定義を見てみましょう!
もし RubyMine を使っていれば、今使ってる gem のコードを覗くのはとっても簡単。
- Project エクスプローラーで External Library を選ぶ
- administrateを選択
- 見てみたい field の定義を選ぶ
administrate/views/fields/image
コードを見てみると、index, showでは image_tag
を使って画像として描画、 form では text_field
を使って文字入力を受け付ける状態でした。
index の中で良い感じに小さい画像で表示されるところが気になる・・・
parcial viewには違いがないので、CSSでスタイル付けしてそうな感じ。。
先ほどの gem のスタイル系のところを漁ってみます。
.collection-data {
@include padding(null $base-spacing);
}
.table__row {
background-color: $white;
border-left: 2px solid transparent;
transition: background-color $base-duration $base-timing;
&:hover {
background-color: $base-background-color;
border-left-color: $blue;
cursor: pointer;
}
img {
max-height: 2em;
}
}
.table__action--destroy {
color: $light-red;
}
.table__row
内に出てくる img
の高さが設定されてます。
表示上だけ小さくしてるわけですね。
gemの選択
これでも良いのですが、やはりアプリないで画像も管理したいところ。
画像系の有名Gemで、Carrierwave か Paperclip か・・
と一度使ったことがある Carrierwave で行こうかと思ったけど、Github searchから、同じく thoughtbot の gem である Paperclip の連携情報を発見したので、Paperclip 採用!
Add example of file upload · Issue #195 · thoughtbot/administrate
↑をフォローしていけば難なく導入できますが、一応やり方を・・
準備
Product モデルの image_url:string
をやめて、Paperclipと連携。
(Paperclip連携は RailsでPaperclipを使ってファイルをアップロードする - Rails Webook などを参考に)
デモのProduct(image_urlアリ)から修正を加えていくので、マイグレーションします。
class AddPaperclipToProduct < ActiveRecord::Migration
def self.up
remove_column :products, :image_url
change_table :products do |t|
t.attachment :image
end
end
def self.down
remove_attachment :products, :image
add_column :products, :image_url, :string
end
end
Product モデルに has_attached_file
と validates_attachment_content_type
を付けて、Paperclipと連携できるようにします。
class Product < ActiveRecord::Base
...
has_attached_file :image, styles: { medium: "300x300", thumbnail: "100x100" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
custom field
それでは、 Paperclip 用のカスタムフィールドを作ってみましょう!
> ./bin/rails g administrate:field paperclip
以下のファイルが生成
- app/fields/paperclip_field.rb
- app/views/fields/paperclip_field/_show.html.erb
- app/views/fields/paperclip_field/_index.html.erb
- app/views/fields/paperclip_field/_form.html.erb
修正箇所
画像のURL、サムネイル画像のURLを返すメソッドを追加。
require "administrate/fields/base"
class PaperclipField < Administrate::Field::Base
def url
data.url
end
def thumbnail
data.url(:thumbnail)
end
def to_s
data
end
end
showページでは縮小なしのオリジナル画像を表示
image_tag
を使う
<%= image_tag field.url %>
indexページでは縮小したサムネイル画像を表示
image_tag
を使う
<%= image_tag field.thumbnail %>
formページでは、ファイルを選択してアップロードできるように
file_field
を使う
<div class="field-unit__label">
<%= f.label field.attribute %>
</div>
<div class="field-unit__field">
<%= f.file_field field.attribute %>
</div>
管理画面側修正
Dashboard
Paperclip が付与してくれたフィールドを追加します。
ATTRIBUTE_TYPES = {
image: PaperclipField,
}
COLLECTION_ATTRIBUTES
, SHOW_PAGE_ATTRIBUTES
, FORM_ATTRIBUTES
にも :image
の呼び出しを追加して、ダッシュボード上に表示される様にしてみます。
今度は index ページでは thumbnail 画像が読み込まれるので、読み込み速度的にも良さそうです。
ページネーション:kaminari
Administrateはデフォルトでいい感じにページネーションしてくれるのですが、 kaminari の default style以外を指定してる場合、レイアウトが崩れる場合があるようです。
namespaceを分ければうまいことアプリ本体側のページネーションスタイルと両立できるようになるようです。
前提例
アプリには kaminari bootstrap styleを使ってる。
> ./bin/rails g kaminari:views bootstrap3
生成ファイル
- app/views/kaminari/_first_page.html.haml
- app/views/kaminari/_gap.html.haml
- app/views/kaminari/_last_page.html.haml
- app/views/kaminari/_next_page.html.haml
- app/views/kaminari/_page.html.haml
- app/views/kaminari/_paginator.html.haml
- app/views/kaminari/_prev_page.html.haml
準備
ページネーションするくらい沢山ダミーデータを生成します。(FactoryGirl使用)
ファクトリでダミーデータの準備
FactoryGirl.define do
factory :customer do
sequence :name, "テストn_1"
sequence(:email){|n| "tester-#{n}@example.com" }
end
end
シード呼び出しの準備
require 'factory_girl'
Customer.destroy_all
FactoryGirl.create_list(:customer, 50)
ダミーデータ生成
> ./bin/rake db:seed
スタイル崩れ
こんな感じでページネーション部分が縦に乗っかってます;;
どうする・・
またもや administrate の issues を掘ります。
これ。近そう!
管理画面側修正
administrate の 全体 index に関する変更なので、ビューページのカスタマイズを実行します。
> rails generate administrate:views:index
生成ファイル
- app/views/admin/application/index.html.erb
- app/views/admin/application/_collection.html.erb
最下部のページネーション部分に views_prefix
を追加。
<%= paginate resources, views_prefix: 'admin' %>
kaminari default theme for administrate
> ./bin/rails g kaminari:views default
ここで生成されるファイルを、 app/views/admin/kaminari
以下に保存。
すると、無事スタイル崩れなしでページネーションが表示される。