fc2ブログ

2023.09 «  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 - - - - » 2023.11
TOP > CATEGORY > RubyOnRails(Model)

BACK | TOP

モデルのテーブル名やプライマリキー名を指定する 

2007年09月06日 ()
Ruby On Rails でアプリを作るぞー、と決める前からあったテーブルを使いたい場合はどうしましょう。

そんな時に心強いのが、set_table_name です。

普通、モデル名の複数形がテーブル名になったりするのですが、モデルファイルで、set_table_name の後にテーブル名を指定してあげると、指定したテーブル名を使ってモデルが機能するようになります。


例を挙げてみましょう。

code_master という古ーいテーブルが昔からあったとします。

$mysql describe code_master;

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| code_desc | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+



それを、OldCodeMaster というモデルで使いたい!という場合は以下のように書けばOK牧場です。

app/models/old_code_master.rb

class OldCodeMaster < ActiveRecord::Base
  set_table_name "code_master"
end




更に、テーブルには普通は id という名前の int 型のプライマリキーを付けるのですが、その名前が違うときには、set_primary_key を使います。

前述のテーブルの最初のカラムが id ではなくて、以下のように code_num というプライマリキーだった場合、

$mysql describe code_master;

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
code_num  | int(11)      | NO   | PRI | NULL    | auto_increment |
| code_desc | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+



次のように書けばOK牧場です。

app/models/old_code_master.rb

class OldCodeMaster < ActiveRecord::Base
  set_table_name "code_master"
  set_primary_key "code_num"
end




更に更に、あるカラムについて、データ内容は変えたくないけれど、モデルで新しい取り出し方や書き込み方をしたい場合は、メソッドを追加(オーバーライド?)します。

以下の例ですと、code_desc には、古いデータは全て小文字で入っているのですけど、今は全て大文字で読み書きしたい!でも、古いデータは小文字のまま残しておきたい!という場合の書き方です。

class OldCodeMaster < ActiveRecord::Base
  set_table_name "code_master"
  set_primary_key "code_num"
  def code_desc # データの読み込み
    read_attribute("code_desc").upcase
  end
  def code_desc=(code) # データの書き込み
    write_attribute("code_desc", code.downcase)
  end

end



【広告】

[2007.09.06(Thu) 20:49] RubyOnRails(Model)Trackback(0) | Comments(0) 見る▼
↑TOPへ

find_by_ とか find_all_by_ とかが真新しい。プレースホルダーのことも触れてます! 

モデルの行オブジェクト(DB テーブルの 1 行とか複数行とかのデータを持っている)をゲットするときに、DB テーブルに検索をかけます。

その時には、find というメソッドを使うと、ゲットできますね。

例えば、people というテーブルに last_name というカラムがあるとします。

その時は、普通、Person モデルを使ってこの people テーブルにアクセスします。

last_name が '片山' という行を探したい場合、この Person モデルファイルの中で、次のようにします。

person = Person.find(:first, :conditions => ["last_name = '片山'"])



ちなみに、SQL インジェクション対策もされているプレースホルダーは、ハテナ(クエスチョンマーク)で表します。? の周りにシングルクォーテーションを付けないように気をつけてね★

searching_last_name = "片山"
person = Person.find(:first, :conditions => ["last_name = ?", searching_last_name])



でも、もっと簡単な書き方もあるのですよ。メソッド名の find_by_ の後に、探しているカラム名を書けてしまうのです。スゴいですね。

person = Person.find_by_last_name('片山')




同じ感じで、find :all も書き換えることができます。
↓の 2 つは同じです!

people = Person.find(:all, :conditions => ["last_name = '片山'"])
people = Person.find_all_by_last_name('片山')




さらにさらに、今日はふとん圧縮袋をもう 1 枚追加いたしまして同じお値段。 and で複数のカラム名をつなげられますのよ。

person = Person.find_by_last_name_and_first_name('ひとみ')



まあ、これですと名字も名前も「ひとみ」という超珍しい人を探していることになりますがね。「人見 瞳」さんとか、いないことはなさそうですけど・・・

【広告】

[2007.08.06(Mon) 17:02] RubyOnRails(Model)Trackback(0) | Comments(0) 見る▼
↑TOPへ

validates_acceptance_of 

モデル model ファイルの中で、validates_acceptance_of を使って、1つのチェックボックス checkbox がチェックされているかどうかを調べることができます。

例えば、なんかの入力フォームがあって、最後に規約に同意しますか?みたいなチェックボックスがあって、それがチェックされていないと入力フォームが送信されない、なーんていうことをしたい場合のチェックの仕方を書いてみます。

たとえば、モデルファイル名が honyararamodel.rb だった場合、

validate_acceptance_of :douisuru



と書きます。

じゃあ、そん時の view ファイルはどうなっているか、というと、

<% form_for :honyararamodel, @honyararamodel do |form| %>
名前を入れてください <%= form.text_field :user_name %><br>
規約に同意しますか? <%= form.check_box :douisuru %><br>
<%= submit_tag "送信する" %><br>
<% end %>



だいたいこういう風になっていると思います。

validate_acceptance_of で指定された値は、honyararamodels テーブルとは全く無関係になります。

今回の例ですと、honyararamodels テーブルに、douisuru カラムがなくても、honyararamodel.rb モデルファイルの中で、あたかも douisuru カラムが存在するかのようにバリデーションを行うことができますし、douisuru チェックボックスの値を、honyararamodels テーブルに保存しません。スゴイナー。

[07/10/04]改訂
validate_acceptance_of と一緒に attr_accessor を定義すると書いていましたが、validate_acceptance_of だけの定義で十分なことが分かり、書き直しました。

【広告】

[2007.08.04(Sat) 17:41] RubyOnRails(Model)Trackback(0) | Comments(0) 見る▼
↑TOPへ

validates_uniqueness_of はなんかスゴい 

モデル model ファイルの中に、いろいろなバリデーションが書けるのですが、validates_uniqueness_of という種類もあります。

指定されたカラムについて、DB のテーブル中のデータに重複があれば、エラーにしてしまう、というマジカルなメソッドです。

例えば

validates_presence_of :favorite_team



なーんてやったりすると、このモデルのテーブルの favorite_team というカラムに、重複した値を insert したり、update したりしようとすると、エラーが出まして、insert したり、update したりできません。

なかなかスゴいエラーチェックだと思いました。

あと、応用編として、範囲を狭めることができます。

validates_presence_of :favorite_team, :scope => :login_name



とすると、同じ login_name を持つ人限定で、重複した favorite_team を複数 insert したり update したり出来なくなります。

分かりづらいかも?じゃあ、例で示してみます。

login_name = 1, favorite_team = 広島
login_name = 2, favorite_team = 巨人

というデータがテーブルの中にあったとして、新たに次のデータは挿入できます。

login_name = 1, favorite_team = 巨人
login_name = 2, favorite_team = 広島

でも、次のデータは挿入できません。

login_name = 1, favorite_team = 広島
login_name = 2, favorite_team = 巨人

というわけでした。

では、Wiedersehen!!

[追記 07/08/05]
でも、もっと調べてみると、これで DB カラムのデータとして唯一であることを保証されないようです。

rails が平行して動いているときに、同じタイミングで、同じカラムに対して、同じ値で validates_presence_of で調べて、どちらもバリデーションが OK と、通ったら、この同じ値が 2 つ DB に保存されることもありうるそうです。

というわけで、究極的には、DB の UNIQUE インデックスなどであるカラムに対するデータの uniqueness を守るしかなさそうです。

例えとしては、ブラウザから入力された値の長さチェックを Javascript クライアントサイドでしても、サーバーサイドで再びもう一回長さチェックをしなければいけないよぉ、という関係に似ているでしょうか。validates_presence_of と DB Unique インデックスは。

分かりづらいですって?その旨、コメント欄にお願いします!そのときはもっと分かりやすい例えを考えるつもりです。

【広告】

[2007.08.02(Thu) 15:07] RubyOnRails(Model)Trackback(0) | Comments(0) 見る▼
↑TOPへ

BACK | TOP