LoginSignup
23
23

More than 5 years have passed since last update.

Rails管理画面gem の新星!administrate を使おう - その3 有名Gemと連携

Last updated at Posted at 2016-02-28

この記事は Rails管理画面gem の新星!administrate を使おう その3です。
関連記事はこちら


他のgemと連携

おなじみの有名gemと連携してみます。
(ここでは有名gemは利用可能な状態で記載していきます)

連携お相手のgemのことがちゃんとわかってればサクッとできる。
(わかってなかったので苦戦・・)

  • 認証 : devise
  • タグ付け:act_as_taggable_on
  • 画像アップロード:paperclip
  • ページネーション:kaminari

認証 : devise

Administrateには認証系の機能は一切ありません。
アプリケーションでお使いの認証機能をこちらにも使ってみます。
一番の有名どころであるDeviseとの連携は簡単!

準備

特になし。
Deviseは使える状態になってるものとします。

管理画面側修正

rails generate administrate:install で生成された application_controller.rb をちょこっと修正します。

app/controllers/admin/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 にタグをつけてみます。

app/models/product.rb
class Product < ActiveRecord::Base
  validates_presence_of :name, :price, :image_url

  acts_as_taggable
  acts_as_taggable_on :category
end

管理画面側修正

Dashboardから操作できるようにします。

イマイチなやり方

category_list をStringで登録できるようにしてみます。

app/dashboards/product_dashboard.rb
  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個のタグが付くの図

新規作成の場合。

image

登録できて、タグも3つ作られている。
よしよし・・・いや・・待て、全然よくない!

問題点

すでに作成されたProduct のupdateをしようとすると、
カテゴリにカンマなくなってる!
(editで戻ってきた時にすでにcategory_list登録済みの場合)

image

このまま登録してしまうと、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

微修正。。。

app/fields/string_tag_field.rb
  def joined
    data.join(',')
  end
app/views/fields/string_tag_field/_form.html.erb
<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

image

コードを見てみると、index, showでは image_tag を使って画像として描画、 form では text_field を使って文字入力を受け付ける状態でした。

index の中で良い感じに小さい画像で表示されるところが気になる・・・
parcial viewには違いがないので、CSSでスタイル付けしてそうな感じ。。

先ほどの gem のスタイル系のところを漁ってみます。

administrate/app/assets/stylesheets/administrate/components/_table.css
.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アリ)から修正を加えていくので、マイグレーションします。

db/migrates/20160228013716_add_paperclip_to_product.rb
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_filevalidates_attachment_content_type を付けて、Paperclipと連携できるようにします。

app/models/product.rb
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を返すメソッドを追加。
app/fields/paperclip_field.rb
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 を使う

app/views/fields/paperclip_field/_show.html.erb
<%= image_tag field.url %>
indexページでは縮小したサムネイル画像を表示

image_tag を使う

app/views/fields/paperclip_field/_index.html.erb
<%= image_tag field.thumbnail %>
formページでは、ファイルを選択してアップロードできるように

file_field を使う

app/views/fields/paperclip_field/_form.html.erb
<div class="field-unit__label">
  <%= f.label field.attribute %>
</div>
<div class="field-unit__field">
  <%= f.file_field field.attribute %>
</div>

管理画面側修正

Dashboard

Paperclip が付与してくれたフィールドを追加します。

app/dashboards/product_dashboard.rb
  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使用)

ファクトリでダミーデータの準備

spec/factories/customers.rb
FactoryGirl.define do
  factory :customer do
    sequence :name, "テストn_1"
    sequence(:email){|n| "tester-#{n}@example.com" }
  end
end

シード呼び出しの準備

db/seeds.rb
require 'factory_girl'

Customer.destroy_all

FactoryGirl.create_list(:customer, 50)

ダミーデータ生成

> ./bin/rake db:seed

スタイル崩れ

image

こんな感じでページネーション部分が縦に乗っかってます;;

どうする・・
またもや administrate の issues を掘ります。

Fixed pagination styles if kaminari already used in Rails-app by mgrachev · Pull Request #203 · thoughtbot/administrate

これ。近そう!

管理画面側修正

administrate の 全体 index に関する変更なので、ビューページのカスタマイズを実行します。

> rails generate administrate:views:index

生成ファイル

  • app/views/admin/application/index.html.erb
  • app/views/admin/application/_collection.html.erb

最下部のページネーション部分に views_prefix を追加。

app/views/admin/application/index.html.erb
<%= paginate resources, views_prefix: 'admin' %>

kaminari default theme for administrate

> ./bin/rails g kaminari:views default

ここで生成されるファイルを、 app/views/admin/kaminari 以下に保存。

すると、無事スタイル崩れなしでページネーションが表示される。

image

23
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
23