Help us understand the problem. What is going on with this article?

RailsAdminと遊ぼう~カスタマイズ戦記~

この記事はウェブクルー Advent Calendar 2019の17日目の記事です。
昨日は@yagiyuuuuさんのNginx + uWSGI + Python(Django)の環境をdockerで作成するでした。

この記事について

弊社は社内のデータ管理ツールにRailsAdminを導入しています。
導入に関してはこちらに過去のアドベントカレンダーで書かれた記事があります。
本記事は、RailsAdminを利用していく上でたまったり社内で共有されている知見や運用中に直面した問題のトラブルシューティングについて書こうと思います。

テーブルの主キーをid以外にしたい

  • シチュエーション:外部キーを主キーとしたい
  • 対応:対象のモデルに下記の1行を追加

app/models/author_introduction.rb

  self.primary_key = :author_id

複合キーも試してみましたがすぐにはできなさそうなのであきらめました。
お勧めしません。

ちなみに、上記の一行を忘れるとモデルの一覧画面を開くとエラーが起きるので注意。

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'desc LIMIT 20 OFFSET 0' at line 1: SELECT  `author_introductions`.* FROM `author_introductions` ORDER BY author_introductions. desc LIMIT 20 OFFSET 0

データをcsvからインポートしたい

  • シチュエーション:初期データを非エンジニアのユーザーが一括で入力できるようにしたい
  • 対応:rails_admin_importを導入

各ファイルに以下を追加。
Gemfile

gem "rails_admin_import", "~> 2.2"

config/initializers/rails_admin.rb

  config.actions do
    all
    import
  end


  # Optional:
  # Configure global RailsAdminImport options
  config.configure_with(:import) do |config|
    config.logging = true
  end

  # Optional:
  # Configure model-specific options using standard RailsAdmin DSL
  # See https://github.com/sferik/rails_admin/wiki/Railsadmin-DSL
  config.model 'User' do
    import do
      include_all_fields
      exclude_fields :secret_token
    end
  end

csvのサンプル。外部キーがある場合は一行目はモデル名を記入。
なんでかエクセルで保存するときに CSV UTF-8を選択するとインポートに失敗するので、素直にShift-JISのcsvで保存するかエディタ使ってUTF-8のデータを作ってください。

Email, Book, Book, Book
peter.gibbons@initech.com, 9781119997870, 9780671027032
michael.bolton@initech.com, 9780446677479

トラブル:インポートの動作確認がしたいのにローカルでうまく動かない

  • シチュエーション:タイトルまま
  • 対応①:rails 再起動
    →model更新後にimportを実行するとエラーになる。対応としてサーバ再起動すればOK。
    https://github.com/stephskardal/rails_admin_import#import-error-due-to-rails-class-reloading

  • 対応②:development.rbの設定を変更
    リクエストのたびにclassを読み込もうとすると、リクエストの処理中にインポート対象のモデルのinstanceが生成されなおしちゃう?っぽいです。
    雑に流し読んだだけなので、詳しくはこちらのISSUEをご覧ください。

  config.cache_classes = true

私が参照したいのはidでもnameでもない

  • シチュエーション:belongs_to で関係づけしているテーブルの、参照元での表示を特定のカラムの値にしたい 補足:RailsAdminでは、参照先の外部テーブルの値は name > id の優先度で参照先のレコードの値が参照している子テーブルに表示される。これを別のものにしたい。
  • 対応:show ブロックの中の該当fieldの設定を以下のように変更 https://github.com/sferik/rails_admin/issues/2356

initializers/rails_admin.rb

RailsAdmin.config do |config|
  config.model 'Book' do
    show do
      field :author do
        pretty_value do value.try(:last_name) end
      end
    end
  end

Edit画面でも↑と同じことがしたい

  • シチュエーション:edit画面で新規データを追加するときに、 belongs_to で関係づけしてるテーブルの特定のカラムを見て参照先レコードを決めたい
  • 対応:editブロックに記述追加

initializers/rails_admin.rb

RailsAdmin.config do |config|
  config.model 'Book' do
    edit do
      field :author, :enum do
       enum do
         Author.all.collect {|a| [a.last_name, a.id]}
       end
    end
  end

editブロックでfieleの値をenum [['表示名', value],[],...] 見たいに与えると、画面上の該当フィールドにはdrop downが表示されるようですね。
入力できる値を制限したいときとかにも使えそう。

モデルの一覧画面でデータを加工して表示したい

  • シチュエーション: has_one で関連付けしてる子テーブルの値があるかないかを親テーブルの一覧画面で見たい
  • 対応:親テーブルにvirtual fieldを追加

注意:悲しいことにこのやり方で表示されるデータは、ソートや絞り込みの基準としては指定できません。

app/models/author.rb

  # Virtual field method
  def introduced
    AuthorIntroduction.exists?(author_id: self.id)
  end

initializers/rails_admin.rb

RailsAdmin.config do |config|
  config.model Author do
    list do
      # virtual field
      configure :introduced do
      end
    end
  end
end

仮想フィールドはいろいろ作れそうです。
詳しくは本家のwikiをどうぞ。

終わりに

サンプルコードを上げようとrailsの環境を作ってたら記事にかける時間が消えました。
結局実装途中なので、今度実装してそのうちこっそりここにサンプルコードのリンクを貼りたいなという面持ちです。
→追記 以下にサンプルコードをアップしました。
https://github.com/tsutsui-yuko/bookshelves

日本語の記事がよく出てる内容は省いて、私自身が調べるときの参照先が英語で書かれたものを今回載せてみました。
ググり力が足りないせいで日本語の記事に普通に書いてある内容だった場合はすみません。
RailsAdminはカスタマイズするのにつらみがあるという共通認識があるかなと思いますが、たくさんの人に使われているだけあって、wikiやissueを調べてみると自分がやりたいことをすでにやってる人が結構いて意外といろいろできそうです。
暇で暇で寝すぎて頭が痛くなってしまったときなどに時間つぶしとして読むと楽しいかもしれません。

「こんな機能もおすすめだよ」というものがありましたらコメントや編集リクエストなどでお知らせくださいますと私が喜びます。

明日の記事は@wc-takaharaさんです。
よろしくお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした