Создать новый экземпляр модели ruby ​​с ассоциациями - PullRequest
0 голосов
/ 04 мая 2011

Возможно, это основной вопрос, но в настоящее время он сводит меня с ума ... Возможно, я что-то упустил, так как я так глубоко погружаюсь в код, но вопрос:

Как можноЯ делаю мой объект с ассоциациями?

У меня есть следующие сценарии миграции:

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

Так что еслиЯ правильно помню свои уроки по Ruby, следующий код должен быть в порядке:

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) не создаются все время 2) никогда не связаны с моими концептуальными объектами.

Чего мне не хватает?

1 Ответ

1 голос
/ 04 мая 2011

Во-первых, я бы предложил упростить этот фрагмент вашего кода примерно так:

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'])

Это не проверено, так что это может быть не совсем правильно.

Во-вторых, проверьте, проходит ли валидация или нет. valid? вернет false, если возникнет проблема проверки, например, если значение PrefLabel не уникально.

Я подозреваю, что вам нужно расширить свои проверки, хотя, конечно, это только предположение.

...