Active Admin使ってみた

# 公式サイト

* [http://activeadmin.info/](http://activeadmin.info/)

# ハンズオン

* [Rails 4 ＆ Active Admin で、マスタCRUD系の管理画面を秒速で作る方法](http://qiita.com/hkusu/items/3b0fb7f94a254e2ed6fd) @hkusuさんの記事


```bash:
sudo apt-get install -y ruby-railties bundler libsqlite3-dev
```

```bash:
rails new act1
cd act1
```

```diff:Gemfile
+ gem 'activeadmin', github: 'gregbell/active_admin'
+ gem 'devise'
```

```bash:
bundle install --path vendor/bundle
```

```bash:
./bin/rails g active_admin:install
./bin/rake db:migrate
./bin/rails s
```

## ログイン

![a1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4f85e987-bfaa-df4e-fa78-b2a7824241fd.png)

http://localhost:3000/admin/login
にアクセス

```rb:db/migrate/20150707221710_devise_create_admin_users.rb
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if direction == :up
```

とのことなので

* admin@example.com
* password

でログイン

## ログイン成功

![a2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/bf1d8958-7e6f-debb-68cc-64a300749f0f.png)

## modelを作成

```bash:
./bin/rails g scaffold Hoge name:string age:integer
./bin/rake db:migrate
./bin/rails generate active_admin:resource Hoge
```

![a3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/98c8e5d0-acbc-c5e9-07e7-81bea9fa7810.png)

上のメニューに`Hoge`が追加された。

* http://localhost:3000/admin/hoges
* http://localhost:3000/admin/hoges/new

newから登録すると以下エラーになるので対策

> ActiveModel::ForbiddenAttributesError in Admin::HogesController#create

```diff:app/admin/hoge.rb 
  ActiveAdmin.register Hoge do
+   permit_params :name, :age
  end
```

登録できた。

![a4.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4d57f97b-cb25-9db7-5c98-97d9d046f340.png)


## databaseの中身確認

./db/development.sqlite3

に保存されています。

```bash:
sudo apt-get install -y sqlite3
```

```bash:
sqlite3 ./db/development.sqlite3
```

```diff:./db/development.sqlite3の中身
  sqlite> .schema
  CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
  CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
  CREATE TABLE "admin_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255) DEFAULT '' NOT NULL, "encrypted_password" varchar(255) DEFAULT '' NOT NULL, "reset_password_token" varchar(255), "reset_password_sent_at" datetime, "remember_created_at" datetime, "sign_in_count" integer DEFAULT 0 NOT NULL, "current_sign_in_at" datetime, "last_sign_in_at" datetime, "current_sign_in_ip" varchar(255), "last_sign_in_ip" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
  CREATE UNIQUE INDEX "index_admin_users_on_email" ON "admin_users" ("email");
  CREATE UNIQUE INDEX "index_admin_users_on_reset_password_token" ON "admin_users" ("reset_password_token");
  CREATE TABLE "active_admin_comments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "namespace" varchar(255), "body" text, "resource_id" varchar(255) NOT NULL, "resource_type" varchar(255) NOT NULL, "author_id" integer, "author_type" varchar(255), "created_at" datetime, "updated_at" datetime);
  CREATE INDEX "index_active_admin_comments_on_namespace" ON "active_admin_comments" ("namespace");
  CREATE INDEX "index_active_admin_comments_on_author_type_and_author_id" ON "active_admin_comments" ("author_type", "author_id");
  CREATE INDEX "index_active_admin_comments_on_resource_type_and_resource_id" ON "active_admin_comments" ("resource_type", "resource_id");
+ CREATE TABLE "hoges" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "age" integer, "created_at" datetime, "updated_at" datetime);

```

```sql:
sqlite> select * from hoges;
1|おなまえ|18|2015-07-07 22:30:28.662739|2015-07-07 22:30:28.662739
```

```sql:
sqlite> select * from active_admin_comments;
1|admin|コメントとか|1|Hoge|1|AdminUser|2015-07-07 22:33:04.617053|2015-07-07 22:33:04.617053
2|admin|コメント追記|1|Hoge|1|AdminUser|2015-07-07 22:33:33.216429|2015-07-07 22:33:33.216429
```

# productionで動かしてみる

* [RailsをローカルでProductionモードで起動させる方法 - Rails Webook](http://ruby-rails.hatenadiary.com/entry/20141110/1415623670)
* [sqlite3 コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/sqlite.html)

## dbのmigrate

developmentではなくproductionで動かす場合、

```bash:
bin/rake db:migrate RAILS_ENV=production
```

> Devise.secret_key was not set. Please add the following to your Devise initializer:

と出るため以下実施

```bash:
bin/rake secret
```

もしくは

```diff:config/initializers/devise.rb
  Devise.setup do |config|
    # config.secret_key = 'e7d789bbdb8...
+   config.secret_key = 'エラーメッセージに表示されたものをそのまま貼り付け'
  end
```

```bash:これで通るようになる。
bin/rake db:migrate RAILS_ENV=production
```

## precompile

```diff:config/environments/production.rb
- config.serve_static_assets = false
+ config.serve_static_assets = true
```

```bash:
bin/rake assets:precompile RAILS_ENV=production
```

## 起動

```bash:
SECRET_KEY_BASE=$(./rake secret) ./bin/rails s -eproduction
```

* 本番のときは、SECRET_KEY_BASEは環境変数に設定し、起動するたびに変更しない
* db/production.sqlite3 に値が保存されることを確認。

```bash:
$ sqlite3 db/production.sqlite3 "select * from hoges"
1|なまえ１|22|2015-07-07 22:55:07.971142|2015-07-07 22:55:07.971142
```


## development/productionの違い

* [Ruby on Rails ～development/productionの違い～](http://www.sakc.jp/blog/archives/34780)

> production ：
> 　・サーバーを再起動しないとコードの変更は反映されない
> 　・Rails本来の性能が出る(レスポンスが良くなる)。
> 
> development：
> 　・appフォルダ以下のコードを変更すると、サーバー再起動せずに、変更内容が即座に反映される。
> 　・レスポンスが悪い(productionに比べ)。
> 
> つまり、developmentにしておくとサーバ再起動が不要なので、ソースをちょこちょこ変更しながら動作確認を行うような開発時には好都合で、本番環境では動作性能のよいproductionを使用すべきということになります。
> 例えばproductionモードで、なかなかソースの修正が反映されないと思っていたら再起動してない、ということが起きたりするので、意識しないといけませんね。

# アカウントの管理

* http://localhost:3000/admin/admin_users にアクセス

![aaccount.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ecc75e72-d8d8-4c82-63ad-17b3383a587f.png)

もしくは手動で追加

```bash:
$ bin/rails c
pry(main)> AdminUser.create!(:email => 'user1@example.com', :password => 'password', :password_confirmation => 'password')
```

# ログインしたら任意のページを表示させる

* [rails, ActiveAdmin remove dashboard page - Stack Overflow](http://stackoverflow.com/questions/17597219/rails-activeadmin-remove-dashboard-page)

```diff:config/initializers/active_admin.rb
- # config.root_to = 'dashboard#index'
+ config.root_to = 'hoges#index'
```

# 大メニューにぶら下げる

* [【Rails】ActiveAdminでモテる管理画面をつくるための１０のテクニック！ « zoomAroid](http://shakezoomer.com/?p=558)

```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
    permit_params :name, :age
+   menu parent: "大メニュー", label: "Hoge", priority: 3
  end
```

![a5.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4f902fbf-ac8a-e946-c871-fb2f2fbd8d5b.png)

# CSVアップロード

```diff:Gemfile
+ gem 'active_admin_importable'
```

```bash:
bundle install --path vendor/bundle
```

```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
+   active_admin_importable do |model, hash|
+     model.create(name: hash[:name], age: hash[:age])
+   end
  end
```

![a6import.png](https://qiita-image-store.s3.amazonaws.com/0/25728/7a8f99a1-65d9-30e5-71ae-791b947d6968.png)

* 右上に`Import Hoge`が追加される
* サンプルデータ作成

```bash:a.sh
echo "name,age"
for i in `seq 1 100`
do
  echo "user$i,$i"
done
```

```bash:
sh a.sh > a.csv
```

取り込み実施

* [Ruby - CSV.open で Encoding::UndefinedConversionError になる場合 - Qiita](http://qiita.com/kano-e/items/19df487e163c606bd652)

## csvファイルをインポートしたら`"\xEF" from ASCII-8BIT to UTF-8`エラー

* [Windows - Encoding::default_externalとEncoding::default_internalをデフォルトでUTF-8にしておく - Qiita](http://qiita.com/kuwa72/items/7019920e634bb8211638)

![aerr.png](https://qiita-image-store.s3.amazonaws.com/0/25728/f95205a3-48f2-7256-c441-cb2f047a772c.png)


```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
    active_admin_importable do |model, hash|
-     model.create(name: hash[:name], age: hash[:age])
+     model.create(name: hash[:name].encode('UTF-8', 'UTF-8'), age: hash[:age].encode('UTF-8','UTF-8'))
+     // もしくは
+     model.create(name: hash[:name].force_encoding('UTF-8'), age: hash[:age].force_encoding('UTF-8'))
    end
  end
```

# 表示のカスタマイズ

## ソート順を指定

```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
+  config.sort_order = "name_asc"
  end
```

## 削除できなくする


```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
+  actions :all, :except => [:destroy] 
  end
```

* `delete`リンクがなくなったことを確認。

![a7destroy.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ad33397a-8b9e-1544-1645-937e3a2fed11.png)

## 表示カラムの指定

 ![a8.png](https://qiita-image-store.s3.amazonaws.com/0/25728/2cfa4290-097b-6171-4584-503d8f419928.png)

```diff:app/admin/hoge.rb
  ActiveAdmin.register Hoge do
+   index do
+     column :id
+     column :name
+     column "年齢", :age
+     column :created_at
+     column :updated_at
+     actions
+   end
  end
```

* actions でview,editのリンクを表示。
* ageカラムの表示を年齢に変更
* 昔は`default_actions`という指定だった。

## タイトルの変更

```diff:config/initializers/active_admin.rb
  ActiveAdmin.setup do |config|
+   config.site_title = "管理画面"
  end
```

![a9.png](https://qiita-image-store.s3.amazonaws.com/0/25728/9df6df8d-14d4-5274-92b8-305a4e5016fe.png)

## 日付フォーマット

* [Dev/active_admin - mononoco Wiki](http://mononoco.com/moin/Dev/active_admin)

```diff:config/locales/en.yml
  en:
    hello: "Hello world"
+   date:
+     formats:
+       long: "%Y-%m-%d"
+   time:
+     formats:
+       long: "%Y-%m-%d %H:%M:%S"
```

![a10date.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0b9864af-21fe-1923-067f-285b6c5cf24c.png)

## TimeZone

* [RailsでTimeZoneを設定する | TechRacho](http://techracho.bpsinc.jp/baba/2011_07_15/3947)

```diff:config/application.rb
  module Act
    class Application < Rails::Application
+     config.time_zone = 'Tokyo'
    end
  end
```

# paperclip

* [Rails 4.1 で Paperclip を使う - Qiita](http://qiita.com/akishin/items/8bc2196500781ded2c0d)
* [thoughtbot/paperclip](https://github.com/thoughtbot/paperclip)

```bash:
sudo apt-get install -y imagemagick
```

```diff:Gemfile
+ gem 'paperclip'
```

```diff:app/models/hoge.rb
  class Hoge < ActiveRecord::Base
+   has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
+   validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
  end
````

```bash:
./bin/rails g migration add_avatar_to_hoges
```

```diff:db/migrate/2015070*_add_avatar_to_hoges.rb
  class AddAvatarToHoges < ActiveRecord::Migration
+   def change
+     add_attachment :hoges, :avatar
+   end
  end
```

```bash:
./bin/rake db:create db:migrate
```

### rollback方法

* [RubyOnRails - Railsの rake db コマンドリスト - Qiita](http://qiita.com/icche/items/e9b08c6b11f762b949de)

もしなかったことにしたい場合は`./bin/rake db:rollback`で戻せる。

> ActiveRecord::PendingMigrationError

が出た場合は

```bash:databaseの中身が消えます！！
./bin/rake db:rollback
./bin/rake db:migrate:reset
```

* app/models/hoge.rb から該当行を削除

### 続き

```sql:確認
$ sqlite3 db/development.sqlite3 ".schema hoges"
CREATE TABLE "hoges" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "age" integer, "created_at" datetime, "updated_at" datetime, "avatar_file_name" varchar(255), "avatar_content_type" varchar(255), "avatar_file_size" integer, "avatar_updated_at" datetime);
```

```diff:app/views/hoges/_form.html.erb
+ <div class="field">
+   <%= f.label :avatar %><br>
+   <%= f.file_field :avatar %>
+ </div>
```

```diff:app/controllers/hoges_controller.rb
  class HogesController < InheritedResources::Base
    private
      def hoge_params
-       params.require(:hoge).permit(:name, :age)
+       params.require(:hoge).permit(:name, :age, :avatar)
      end
  end
```

途中...