2011-05-04 64 views
0

這可能是一個基本的問題,但它目前讓我瘋狂......也許我失去了一些東西,因爲我在代碼中跳得太深,但問題是:與協會創建新的紅寶石模型實例

如何使我的對象與關聯?

我有以下遷移腳本:

class CreateConcepts < ActiveRecord::Migration 
    def self.up 
    create_table :concepts do |t| 
     t.integer :language_id, :null => false 
     t.string :uri 
     t.integer :isco_code 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :concepts 
    end 
end 

class CreatePrefLabels < ActiveRecord::Migration 
    def self.up 
    create_table :pref_labels do |t| 
     t.integer :language_id 
     t.integer :concept_id 
     t.string :value 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :pref_labels 
    end 
end 

class CreateLanguages < ActiveRecord::Migration 
    def self.up 
    create_table :languages do |t| 
     t.string :code 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :languages 
    end 
end 

這些對象的類如下所示:

class Concept < ActiveRecord::Base 
    belongs_to :language 
    has_one :pref_label 
    validates_uniqueness_of :isco_code 
end 

class PrefLabel < ActiveRecord::Base 
    belongs_to :language 
    belongs_to :concept 
    validates_uniqueness_of :value 
end 

class Language < ActiveRecord::Base 
    has_many :concepts 
    has_many :pref_labels 
    validates_uniqueness_of :code 
end 

所以,如果我沒有記錯我的紅寶石的經驗教訓,下面的代碼應該是完美的罰款:

concept = Concept.first 
concept.pref_label 
language = Language.find(:code => "en") 
language.pref_labels 
language.concepts 

所以我寫了下面的代碼行。內部有點暗,但我100%肯定從JSON數據生成的哈希是正確的。與調試器選中此:

# This function will retrieve all the top most concepts from the ESCO API in the 
    # specified language as an array of Ruby objects, each represented by the relevant class. 
    # If the relevant concept does not exist in the database, the entry is automatically created. 
    # The function will fall back to English by default if no language is specified 
    def self.top_concepts(lang = Language.find_by_code('en') || Language.create(:code => 'en')) 
    concepts = [] 
    json = HTTParty.get "#{Setting[:api]}/getTopmostConcepts?language=#{lang.code}" 
    collection = JSON.parse json.parsed_response 
    collection.each do |c| 
     language = Language.find_by_code c['language'] || Language.create(:code => c['language']) 
     concept = Concept.create(:language => language, :uri => c['uri']['uri'], :isco_code => c['iscoCode'].to_i) 
     label = PrefLabel.find_by_concept_id(concept.id) || PrefLabel.create(:language_id => language.id, :concept_id => concept.id, :value => c['prefLabel']['string']) 
     concept.pref_label= label 
     concept.save 
     concepts << concept 
    end 
    return concepts 
    end 

我現在遇到的問題是,我的PrefLabels是: 1)不beeing創造了所有的時間 2)永遠不會鏈接到我的概念的對象。

我錯過了什麼?

回答

1

首先,我建議簡化您的代碼的這個片段有點像這樣:

language = Language.find_or_create_by_code(c['language']) 
concept = langauge.concepts.create(:uri => c['uri']['uri'], :isco_code => c['iscoCode'].to_i) 
concept.pref_label = PrefLabel.find_or_create_by_concept_id(:concept_id => concept.id, :language_id => language.id, :value => c['prefLabel']['string']) 

這是未經測試,因此可能不完全正確。

其次,檢查驗證是否通過。如果存在某種類型的驗證問題,例如,如果PrefLabel值不唯一,則valid?將返回false。

我懷疑你需要確定你的驗證範圍,雖然這只是一個猜測。

+0

你是對的,範圍缺失 – 2011-05-04 14:31:55