2012年10月30日火曜日

rails g のロールバック

rails g もしくは、 rails generate でファイルを生成した際に、名前を間違えたからやり直したい場合があると思います。
その際には、一個ずつ消さなくても、rails destroyで元通りにしてくれます。
いつもrollbackと打とうとして忘れるんですよね。。destroyです。

$ rails g model latest_info
      invoke  active_record
      create    db/migrate/20121030042916_create_latest_infos.rb
      create    app/models/latest_info.rb
      invoke    rspec
      create      spec/models/latest_info_spec.rb

infos って微妙と思い…。

$ rails destroy model latest_info
      invoke  active_record
      remove    db/migrate/20121030042916_create_latest_infos.rb
      remove    app/models/latest_info.rb
      invoke    rspec
      remove      spec/models/latest_info_spec.rb

画面に表示させるテキストの改行処理方法

DBからデータ取得をして、画面に表示させる際に、\n を <br/>にしたい場合
gsubで、\n を <br /> に変換しなくても simple_format という便利なライブラリがあります。
こんな感じに書くだけ!
<%= h simple_format(text) %>
http://railsdoc.com/references/simple_format
文字列を<p>で括る
改行は<br />を付与
連続した改行は、</p><p>を付与


人によっては、生成される<p>タグがうざいと思う人もいるかも…。

2012年10月19日金曜日

HTMLの表のカラム幅指定

HTMLでTableタグを使って表を作る場合、先頭のカラムのみ固定して、
残りを文字数に関係なく等間隔にしたい場合の方法。
テーブルタグのスタイルに table-layout:fixed; を設定する。

こうするだけで、tdにwidthを設定したものだけ固定され、
他は等間隔になります。colspan, rowspanを使っていても問題なし!

<table border=1 width="100%" style="table-layout: fixed;">
  <tr>
    <th width="100px">Col ABC</td>
    <th>Col ABCDE</td>
    <th>Col3 ABCDE FGHIJ</td>
    <th>Col4</td>
  </tr>
</table>

jQueryのtoggle

リンクを押すとテーブルの表示・非表示をするのに、jQueryのtoggleを利用。

表示・非表示したい部分をdivタグで囲む。
画面表示時は表を表示させたくない場合に、style="display: none"をつける。
<div id = "my_table" style="display: none">
  <table>
    ...
  </table>
<div>

jQueryが入ってることを前提とし、下記のJavaScriptを追加
なお、toggleの引数は、fast, slow, なし 等の設定ができる。
http://api.jquery.com/toggle/
<script type="text/javascript">
function toggleDiv(divId) {
   $("#"+divId).toggle('fast');
}
</script>

選択するリンクにJavaScriptの呼び出しを追加
<a href="javascript:toggleDiv('my_table');" style="text-decoration: none;">Click!</a>





2012年10月17日水曜日

カスタムバリデーションの作り方

Rails3でカスタムバリデーションを作ってみました。
Rails2ですら作ったことなかったのですが、思ったより簡単でした。

config定義
バリデーションクラスを置く場所を定義します。
# config/application.rb
config.autoload_paths += %W(#{config.root}/lib/validators)

バリデーションクラス
options[:message]がバリデーションチェック対象の項目名。
今回はリポジトリ名(name)になりますが、
「リポジトリ名は存在しません。」というようなエラーになります。
# lib/validators/repo_presence_validator.rb
class RepoPresenceValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    unless mail_groups(value)
      object.errors[attribute] << (options[:message] || "は存在しません")
    end
  end

private
  def mail_groups(value)
   ...
  end
end

モデル
青字部分が今回作ったバリデーションを呼んでる所になります。
validates :name, :presence => true, :repo_presence => true
<参考>
http://railscasts.com/episodes/211-validations-in-rails-3
http://hajimete-ruby.jugem.jp/?eid=69

2012年10月9日火曜日

複数テーブルのJOIN

ActiveRecordを使って、複数テーブルのJOINをする際にincludesを使う場合、
複数テーブルをどうやって指定すれば良いのだろうと調べてました。

ひとまず忘れないうちにメモっておきます。

1テーブルのみJOINする場合は、下記のようにかけるのですが、
さらに遡リたい場合はどうすればよいのだろうと。
下記は、projectsがclient_idを持ってるイメージ。
Project.includes(:client)

2テーブルJOINする場合は、下記のように配列とハッシュの組み合わせになります。
こんなふうに書くと、どんどん遡ってかけます。
下記は、teamsがproject_idを持っていて、projectsがclient_idを持ってるイメージ。
Team.includes(:project => [:client])
さらにwhere句を付ける場合は、下記のようにテーブル名をつけてあげます。
Team.includes(:project => [:client]).where("clients.code = ? ", code)

ActiveRecordでIN句

ActiveRecordではIN句を記載するwhereに配列を渡すことができます。
Rails3では下記の書き方になります。
login_ids = ["sato", "suzuki", "tanaka"]
@users = User.where(["login in (?)", login_ids])

こう書くことで、下記の文が実行されます。
SELECT `users`.* FROM `users` WHERE (login in ('sato','suzuki','tanaka'))