AB Lab

abgata20000 blog.

RailsのScaffoldのテンプレートをカスタマイズする

Scaffoldで生成されるテンプレートをSlimに変更する

RailsのScaffoldを使う際にテンプレートをslimで、

生成してさらに中身をカスタマイズできるようにしたくなったのでいろいろ調べてみました。

テンプレートエンジンをslimに変更するのは、簡単そうです。

Gemfileに gem 'slim-rails' を追加して bundle install を実行して、

config/application.rb

1
2
3
config.generators do |g|
  g.template_engine :slim
end

を追加するだけで出来ました。

img

さらに、これの中身をカスタマイズしたい

参考サイト: rails g scaffold のカスタマイズ

現在利用しているテンプレートのコピーを作成します

1
rake rails:templates:copy

これで lib/templates が生成されます

lib/template/scaffold 作成して、

index.html.erb などのテンプレートファイルを作成すれば

rails g scaffold 時に反映されるようです。

テンプレートのカスタマイズもSlimで書きたい

デフォルトでは、テンプレートエンジンは erb になっています。

このままでも良かったのですが、折角なので、

テンプレートのカスタマイズもslimで出来るようにしました。

1
rails g generator slim/scaffold

で、lib/generators/slim/scaffold が生成されます。

生成されたフォルダ内の

scaffold_generator.rb

を編集します。

scaffold_generator.rb
1
2
3
4
5
6
7
8
9
require "rails/generators/erb/scaffold/scaffold_generator"
class Slim::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
  source_root File.expand_path('../templates', __FILE__)

  protected
  def handler
    :slim
  end
end

これで、scaffold時に lib/generators/slim/scaffold/template 内のファイルが利用されるようになります。

index.html.slim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
h1
  | <%= plural_table_name %>

table class=("table table-boderd table-striped table-hover")
  thead
    tr
<% attributes.reject(&:password_digest?).each do |attribute| -%>
      th <%= attribute.human_name %>
<% end -%>
      th
      th
      th

  tbody
    - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
      tr
<% attributes.reject(&:password_digest?).each do |attribute| -%>
        td= <%= singular_table_name %>.<%= attribute.name %>
<% end -%>
        td= link_to 'Show', <%= singular_table_name %>, :class => 'btn btn-info'
        td= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>), :class => 'btn btn-success'
        td
          = link_to('Destroy',
            <%= singular_table_name %>,
            method: :delete,
            :remote => true,
            :onclick => 'if(window.confirm("are you sure?")){$(this).closest("tr").fadeOut()}',
            data: {},
            :class => 'btn btn-danger')

こんな感じですね。

ちょっとハマったのは、

1
2
3
<% attributes.reject(&:password_digest?).each do |attribute| -%>
      th <%= attribute.human_name %>
<% end -%>

のようなscaffold時に生成される箇所にインデントがあると、

生成されたslimファイルのインデントがおかしくなるという点です。

1
2
3
4
5
6
tbody
  - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
    tr
      <% attributes.reject(&:password_digest?).each do |attribute| -%>
      td= <%= singular_table_name %>.<%= attribute.name %>
      <% end -%>

のように記述すると

1
2
tr
    td

とインデントが余分に入ってしまいました。

折角なのでcontrollerとmodelもカスタマイズする

controllerは、lib/templates/rails/scaffold_controller/controller.rbを編集すればいいようです。

このファイルは、最初に実行した

1
rake rails:templates:copy

で生成されていました。

modelは、lib/templates/active_record/model/model.rbを作成する必要があります。

サンプルは、

ruby:model.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<% module_namespacing do -%>
class <%= class_name %> < <%= parent_class_name.classify %>
<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
  belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
<% end -%>
<% if !accessible_attributes.empty? -%>
  # attr_accessible <%= accessible_attributes.map {|a| ":#{a.name}" }.sort.join(', ') %>
<% else -%>
  # attr_accessible :title, :body # rails4 だとエラー出ます
<% end -%>


  def to_s
    <%- if attributes.map{ |a| a.name }.include?('name') -%>
    name
    <%- else -%>
    "<%= class_name %> #{id}"
    <%- end -%>
  end

end
<% end -%>

こんな感じです。

1
rails g scaffold sample name comment:text

img

で生成されるファイルが変更されたのを確認できます。

さて、どんなテンプレートにしようかな。

migrationのテンプレートカスタマイズ

lib/templates/migration/templates/create_table_migration.rb

Expressを使ってみる(Jade、LESS、CoffeeScript)

npmでグローバルにインストール

1
npm install -g express

express コマンドを実行してみる

1
express myApp

img

そんなものはないと怒られる。

少し調べてみた結果、express コマンドには express-generator が必要らしい

1
npm install -g express-generator

再チャレンジしてみる

1
express myApp

img

できた。

expressを起動してみる

まずは設定

1
2
3
cd myApp
npm install
node app

あれ、何も起きない。。。

起動ファイルが、 app.js ではなく、 bin/www らしい

package.json の start コマンドに設定されていた。

1
npm start

img

できた。

CSSをLESSで書きたい

html の テンプレートエンジンはデフォルトで jade だったので、

このまま使うとして CSS は LESS を使いたいと言うことで、

less.js-middleware

を設定してみた。

まずは、npmでインストール

1
npm install less-middleware --save

次に設定ファイルを変更

app.js
1
2
3
4
5
6
// use css engine less
var lessMiddleware = require('less-middleware');

app.use(lessMiddleware(
  path.join(__dirname, 'public')
));
public/stylesheets/style.less
1
2
3
4
5
6
7
8
9
10
h1{
  color: green;
}
#main
{
  color:#FFF;
  #sub{
    color:#666;
  }
}

アクセスしてみる

img

できた。

これだと、public/stylesheets にlessファイル置かないといけないので

lessファイルの配置場所を変更

app.js
1
2
3
4
5
6
7
8
9
// use css engine less
var lessMiddleware = require('less-middleware');

app.use(lessMiddleware(
  path.join(__dirname, 'assets'),
  {
    dest: path.join(__dirname, 'public')
  }
));

これで asets/stylesheets にless ファイルを配置すればOK

CoffeeScriptで記述できるようにしたい

参考 express.js 4をCoffeeScriptで開発できるようにする

coffee-script と js2coffee をインストールする

1
npm install -g coffee-script js2coffee

jsファイルをcoffeescriptに変換

1
find . -type f -name "*.js" | while read f; do js2coffee "$f" > "${f%.*}.coffee"; done

ここで大量のエラーが。

node_modulesの中身にまで変換かけているっぽいですね。

スクリプト修正しようかと思ったが、

既にわけがわからなくなっているので、

復習も兼ねて、最初から作り直すことに

1
2
express myApp
cd myApp

npm install をする前に

1
find . -type f -name "*.js" | while read f; do js2coffee "$f" > "${f%.*}.coffee"; done

今度は大丈夫みたいです。

jsファイルを削除

1
find . -type f -name "*.js" | xargs rm -f

ここで

1
2
npm install
npm install coffee-script --save

スタートアップファイルを編集

bin/www の先頭に以下を追記
1
require('coffee-script/register');

実行してみる

1
npm start

img

できた

外部ファイルもCoffeeScriptで書きたい

あとは、 public/javascripts のファイルもCoffeeScriptで書けるようになれば、

やりたいことは叶いますね。

coffee-middleware がよさそうなのでインストールしてみる

1
npm install coffee-middleware --save

設定ファイルを編集

app.coffee
1
2
3
4
5
6
7
8
# use coffeescript
coffeeMiddleware = require('coffee-middleware')

app.use coffeeMiddleware(
  src: path.join(__dirname, "public")
  compress: true
  bare: true
)

CoffeeScriptのファイルを配置してみる

public/main.coffee
1
alert 'main coffee'

実行してみる

img

できた。

とりあえず、

やりたいことは、出来るようになったので満足なのですが、

実際の運用を考えたら、

html はともかく

js や css は、

毎回expressで生成するのもどうかというわけで、

多分 grunt を使うことになるだろうなと思いました。

MacBookPro が頻繁にフリーズするのでディスクを修正してみた

MacBookPro Early 2013

ディスクユーティリティで ディスクを検証 をクリック

ディスクユーティリティ

待つこと数分、

「ディスクが壊れているのでRecorvery HD でディスクを修復してください」といった感じのメッセージが出てきた。

再起動してappleマークが表示されている間 cmd + R を長押しして ディスクユーティリティを選択

ディスクを検証して、エラーが出たら、ディスクを修正

10分強くらいでディスクが修正されました。

これで治ったらいいな。

Vagrant共有フォルダをnfsを使って高速化する

先日、Vagrantの共有フォルダがデフォルト設定だと遅くて使いものにならないという話を聞き、nfsを使って高速化してみた時の話

nfsd が起動しているかを確認

1
sudo nfsd status

起動していなければ起動する

1
sudo nfsd enable

/etc/exports が必要らしいので作成

1
sudo touch /etc/exports

あとは、設定ファイルで :type に nfs を指定するだけでよさそう

Vagrantfile
1
config.vm.synced_folder ".", "/vagrant", type: "nfs", :mount_options  => ['nolock,vers=3,udp']

簡単ですね。

と思ったのですが

マウント時に何やらエラーが出ているみたいです。

error

rpc.statd を起動させるか オプションで nolockを指定しろと言っているみたいなので、

マウント時のオプションに nolock 渡すようにしたら出来ました。

Vagrantfile
1
config.vm.synced_folder ".", "/vagrant", type: "nfs", :mount_options  => ['nolock,vers=3,udp']

確かになん速い気がします。

今度計測してみよう。

Vagrantでpackage作成した際にVirtualBoxのVersionが異なる場合の対処法

そもそも Vagrant 使おうと思いたった経緯

以前 ドットインストール さんにレッスンがあったので

試してみたことはあったのですが、

自分の環境で利用している「pallarels desctop」と相性が悪いのか、

同時に立ち上げるとMacが落ちるという現象があったため利用はしていなかったのです。

がしかし

先日アホなミスをしてしまい、Macを初期化するハメになってしまい、

データや環境の復旧はだいたいできたのですが、

Rubyの環境がどうしてもうまく構築できなくなってしまったため、

これまで、スクリプトの実行をMacで行っていたのを

「Vagrant」を使って仮想環境を構築してそこで実行するようにしようと思いったたのがことのはじめです。

vagrant の box を作成してみる

折角環境を作ったのでboxを作ってみました。

1
vagrant package

少し時間はかかりましたが問題なく package.box が生成されました。

生成された package.box を vagrant に登録して

1
vagrant box add myImage package.box
Vagrantfile
1
config.vm.box = "myImage"

新しく仮想環境を作成してみようとした所、エラーが発生してしまいました。

1
vagrant up

エラー

仮想環境自体は作成されて ssh接続は出来るのですが、どうやら共有フォルダがマウントされていないようです。

共有フォルダを利用できるようにする

少し調べていた結果、 VirtualBox のバージョンがbox作成時と現在とで異なっているのが原因らしいです。

Vagrantの共有ディレクトリ設定でものすっごい躓いた! を参考に問題を解決してみることに

VirtualBoxのバージョン違いを解決するプラグインをインストールする

1
2
vagrant plugin install vagrant-vbguest
vi ~/.vagrant.d/Vagrantfile
javascript:~/.vagrant.d/Vagrantfile
1
2
3
Vagrant.configure("2") do |config|
  config.vbguest.auto_update = false
end

バージョンが異なっているかどうかを確認

1
2
3
vagrant vbguest --status

 GuestAdditions versions on your host (4.3.10) and guest (4.2.16) do not match.

やはりバージョンが違うらしい

1
vagrant vbguest --auto-reboot

で修正してくれるらしいので実行してみた。

無事終了したっぽいので確認

1
2
3
vagrant vbguest --status

GuestAdditions 4.3.10 running --- OK.

解決したらしい。

Vagrant をリブートしてみる

1
2
3
4
5
6
7
8
9
10
11
12
13
14
v reload
~~~
==> default: Configuring and enabling network interfaces...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

ARPCHECK=no /sbin/ifup eth1 2> /dev/null

Stdout from the command:

Device eth1 does not seem to be present, delaying initialization.


Stderr from the command:

ダメみたい。

IPアドレスがうまく振り当てられていないみたいなので、

ここを参考に少し修正してみる

Vagrant にSSH接続して後に

1
2
sudo ln -s /opt/VBoxGuestAdditions-4.3.10/lib/VBoxGuestAdditions /usr/lib/VBoxGuestAdditions
sudo ln -s /opt/VBoxGuestAdditions-4.3.10/lib/VBoxGuestAdditions /usr/lib64/VBoxGuestAdditions

を実行

リブートしてみる

1
vagrant reload

解決した。

なかなか大変でした。

wheneverでRailsのタスクをcronで実行する

参考サイト

登録内容の確認

1
bundle exec whenever

を実行するとcrontabの内容をコンソール出力。 この時点ではまだcrontabに登録されてはいない。

Crontabへ登録

1
bundle exec whenever --update-crontab

–update-crontabオプションをつけるとcrontabに登録する。 Whenever以外で登録されていたジョブが上書きされることはない。

Crontabから削除

1
bundle exec whenever --clear-crontab

Cronを止めたい場合は–clear-crontabですべて削除。 登録の場合と同様にWhenever管理外のジョブが削除されることはない。

Webminをインストール

参考:

インストールに必要なパールモジュールをインストールする

1
 yum -y install perl-Net-SSLeay

最新版を入手

公式サイト

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir /downloads
cd /downloads

wget http://download.webmin.com/download/yum/webmin-1.630-1.noarch.rpm

rpm -Uvh webmin-1.630-1.noarch.rpm

# アクセス制限を掛ける場合
cp /etc/webmin/miniserv.conf /etc/webmin/miniserv.conf.org
vim /etc/webmin/miniserv.conf


 # 最終行:アクセス許可するIP追記
allow=127.0.0.1 10.0.0.0/24

再起動

1
service webmin restart

SSLの設定

1
2
3
4
5
# sslモジュールをインストール
sudo yum -y install mod_ssl

cp /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.org
vim /etc/httpd/conf.d/ssl.conf

SSL証明書の発行方法

SSL証明書の発行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd /etc/pki/tls/certs
# 鍵ファイル作成用の乱数を発行
openssl md5 * > my_rand.dat

# 鍵ファイルを作成
openssl genrsa -rand my_rand.dat -des3 2048 > my_key.pem

# 鍵ファイル内にパスプレーズを埋め込む
openssl rsa -in my_key.pem -out my_key.pem

# ssl認証局提出用のcsrファイルを作成※このままでは使えません
openssl req -new -key my_key.pem -out my_csr.pem

# オレオレ証明書を作成
openssl req -new -x509 -days 3650 -key my_key.pem -out my_crt.pem


アクセス権変更
chmod 400 my_key.pem
chmod 400 my_crt.pem


vim /etc/httpd/conf.d/ssl.conf
/etc/httpd/conf.d/ssl.conf
1
2
3
SSLCertificateFile /etc/pki/tls/certs/my_crt.pem

SSLCertificateKeyFile /etc/pki/tls/certs/my_key.pem

apacheを再起動して設定を反映

1
service httpd restart

Sambaでネットワークフォルダを作成

sambaをインストール

1
yum -y install samba system-config-samba samba-common samba-client

設定ファイルを変更

1
2
cp /etc/samba/smb.conf /etc/samba/smb.conf.org
vim /etc/samba/smb.conf
/etc/samba/smb.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
;ワークグループ編集(windowsのものと同じにする。macは関係なし?)
workgroup = workgroup

;日本語設定
unix charset = UTF-8
dos charset = CP932
display charset = UTF-8

;受け付けるipを設定
;127.で、127.xx.xx.xxを許可
;hosts allow = 127.192.168.1など

;パスワードをunixパスワードと同じに。
unix password sync = yes
load printers = no

;ホームディレクトリの設定
[homes]
        comment = Home Directories
        browseable = no
        writable = yes
        create mask = 0664
        directory mask = 0755
        create mode = 0775
        directory mode = 0755
      ;valid users = user1,user2,user3,user4,user5
      share modes = yes
          dos filetimes = yes

;共通のpublicフォルダも設定
[public]
        comment = Public Stuff
        path = /home/public
        create mask = 0666
        directory mask = 0755
        guest only = no
        guest ok = no
        public = yes
        writable = yes
      share modes = yes
          dos filetimes = yes

sambaにユーザ追加

1
2
3
4
5
adduser myuser
passwd myuser
pdbedit -a -u myuser

pdbedit -L

samba起動

1
2
service smb start
service nmb start

問題なければ、自動起動に。

1
2
chkconfig smb on
chkconfig nmb on

samba用にiptables編集(下記を追加)

1
2
3
-A INPUT -p udp -m udp --dport 137:138 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 139 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 445 -j ACCEPT

iptables再起動

1
service iptables restart