天天看點

Rails Cookbook翻譯(五)

(本翻譯純粹為了學習,切勿用于商業目的,轉載請指明出處:http://blog.csdn.net/fuliangliang)

Rails Cookbook翻譯(五)

Recipe 3.5 在Rails控制台上觀察模型關系

問題:

   你想檢視你的模型對象之間的關系以便确認你已經正确進行了設定。你可以啟動web程式來這麼做,但你想把事情做得簡單點,那何妨勞駕一下指令行呢。

解決方案:

   使用Rails控制台建立模型對象,并且建立它們之間的關系。

在你的工程根目錄下,輸入:

 ~/projects $ ruby script/console –s

Loading development environment in sandbox.

Any modification you make will be rooled back on exit.

你可以在windows下,使用:

C:/myApp>ruby script/console -s
        

你接着進入了irb會話,可以完全通路你的工作環境和Active Record模型了。你可以輸入Ruby代碼,就像在控制器裡一樣,這樣你可以發現你的資料模型中的任何問題了。

讨論:

作為一個示範,我們為工程建立了一個資料庫,用它來跟蹤assets和它的types。這個例子也與assets和tags關聯。通過使用script/generate:asset,asset_type,以及tag産生的三個模型來建立資料庫(注意:你不想為assets_type連接配接表建立一個模型,因為Rails内部會處理這些)。

~/project$ ruby script/generate model asset
        
...
        
~/project$ ruby script/generate model asset_type 
        
...
        
~/project$ ruby script/generate model tag
        
...
        

現在,我們使用了下面的migration來定義表:

Class BuildDb < ActiveRecord::Migration

def self.up

  create_table :asset_types do |t|

t.column :name, :string

  end

  create_table :assets do |t|

     t.column :asset_type_id, :integer

     t.column :name   :string

     t.column :decription :text

  end

  create_table :assets_tags do |t|

  t.column :name, :string

end

create_table :assets_tags do |t|

  t.column :asset_id, :integer

  t.column :tag_id , :integer

end

end

def self.down

  drop_table :assets_tags

  drop_table :assets

  drop_table :asset_types

  drop_table :tags

end

end

現在你可以使用一些啞資料來操作資料庫了。使用下面的insert語句:

 insert into asset_types values (1,'Photo');
        
insert into asset_types values (2,'Painting');
        
insert into asset_types values (3,'Print');
        
insert into asset_types values (4,'Drawing');
        
insert into asset_types values (5,'Movie');
        
insert into asset_types values (6,'CD');
        
insert into assets values (1,1,'
  
   
    Cypress
   
  ','A photo of a tree.');
        
insert into assets values (2,5,'Blunder','An action film.');
        
insert into assets values (3,6,'Snap','A recording of a fire.');
        
insert into tags values (1,'hot');
        
insert into tags values (2,'red');
        
insert into tags values (3,'boring');
        
insert into tags values (4,'tree');
        
insert into tags values (5,'organic');
        
insert into assets_tags values (1,4);
        
insert into assets_tags values (1,5);
        
insert into assets_tags values (2,3);
        
insert into assets_tags values (3,1);
        
insert into assets_tags values (3,2);
        

現在設定這些模型之間的關系。這個例子包含了一對一和一對多的關系。

asset_type.rb

class AssertType < ActiveRecord::Base

 has_many :assets

end

tag.rb

class Tag < ActiveRecord::Base

 has_and_belongs_to_many :assets

end

assert.rb

class Assert < ActiveRecord::Base

 belongs_to :asset_type

 has_and_belongs_to_many :tags

end

既然我們已經設定好了模型,加載了一些資料,我們可以打開一個控制台會話來看看了:

~/project$ ruby script/console -s
        
Loading development environment in sandbox.
        
Any modifications you make will be rolled back on exit.
        
>> a = Asset.find(3)
        
=> #<Asset:0x4093fba8 @attributes={"name"=>8220;Snap", "id"=>"3",
        
"asset_type_id"=>"6", "description"=>"A recording of a fire."}>
        
>> a.name  
        
=> "Snap" 
        
>> a.description
        
=> "A recording of a fire." 
        
>> a.asset_type 
        
=> #<AssetType:0x4093a090 @attributes={"name"=>"CD", "id"=>"6"}>
        
>> a.asset_type.name
        
=> "CD" 
        
>> a.tags
        
=> [#<Tag:0x40935acc @attributes={"name"=>"hot", "tag_id"=>"1", "id"=>"1",
        
"asset_id"=>"3"}>, #<Tag:0x40935a90 @attributes={"name"=>"red", "tag_id"=>"2",
        
"id"=>"2", "asset_id"=>"3"}>]
        
>> a.tags.each { |t| puts t.name }
        
hot
        
red
        
=> [#<Tag:0x40935acc @attributes={"name"=>"hot", "tag_id"=>"1", "id"=>"1",
        
"asset_id"=>"3"}>, #<Tag:0x40935a90 @attributes={"name"=>"red", "tag_id"=>"2",
        
"id"=>"2", "asset_id"=>"3"}>]
        

在這個控制台會話中,我們使用id為3的參數擷取了asset紀錄,并且将它存到一個對象中。我們顯示了對象的名字和描述。通路asset的類型,傳回了一個AssetType對象。下一行傳回了asset type的名字。

通路asset對象的tags,傳回了一個包含asset的tags對象數組。下一個指令跌代的通路這些tags并且傳回了tag的名字。

當一個對象變得更大更複雜時,在控制台上列印出來的資訊變得非常難讀。通過使用pp(pretty-print)或者y(yaml)來列印模型,可以很大程度的改善資訊的可讀性。在控制台上使用下面的指令:

  require 'pp'
        
asset = Asset.find(:first)
        
pp asset
        
y asset      

y方法以YAML格式列印,使用:

 puts asset.to_yaml  

真是是一個捷徑。

在一個裸露的環境裡測試你的模型是确定你的模型沒有問題的很好的方法。在你應用程式的控制器裡做類似的測試會使得一個很明顯的問題變得很難發現。

你還可以參考:

10.1章