2012-03-16 2 views
2

Я разрабатываю тестовое приложение для изучения Rails. Во время игры с ассоциациями я получаю ошибку ActiveModel::MissingAttributeError: can't write unknown attribute 'linked_section_id'.Ошибка для отношения «один-к-одному»: ActiveModel :: MissingAttributeError: невозможно записать неизвестный атрибут

Позвольте мне сначала объяснить требование. Пользователь выбирает раздел для просмотра. В конце каждого раздела будет несколько вопросов, которые связаны с некоторыми другими разделами. Если пользователь нажимает ссылку на любой вопрос, он будет перенаправлен в соответствующий раздел.

Так сущности отношение, как описано ниже:

  • Раздел может иметь несколько вопросов (один ко многим)
  • вопрос принадлежит к одной секции только (многие к одному - оборотная сторона одного многим)
  • вопрос может быть связан с другим сечением (один к одному)

Окружающая среда: рубин 1.9.3, Rails 3.2.2 со всеми необходимыми самоцветами

здесь классы моделей:

class Section < ActiveRecord::Base 

    # Associations 
    has_many :questions 

end 

class Question < ActiveRecord::Base 
    belongs_to :section, :foreign_key => :section_id 
    has_one :linked_section, :class_name => "Section", :foreign_key => "linked_section_id" 
end 

db/schema.rb 
. 
. 
create_table "sections", :force => true do |t| 
    t.string "name" 
    t.string "content" 
    t.datetime "created_at", :null => false 
    t.datetime "updated_at", :null => false 
    end 
create_table "questions", :force => true do |t| 
    t.string "description" 
    t.integer "section_id" 
    t.integer "linked_section_id" 
    t.datetime "created_at",  :null => false 
    t.datetime "updated_at",  :null => false 
    end 
. 
. 

Вот спецификации.

question_spec.rb 
require 'spec_helper' 

describe Question do 
    before do 
     @question = Question.new(description:'Test') 
    end 

     subject { @question } 

     # Check for attribute accessor methods 
     it { should respond_to(:description) } 
     it { should respond_to(:section) } 
     it { should respond_to(:linked_section) } 
     it { should respond_to(:linked_section_id) } 
end 

section_spec.rb 
require 'spec_helper' 

describe Section do 
    before do 
     @section = Section.new(name:'Test') 
    end 

     subject { @section } 

     # Check for attribute accessor methods 
     it { should respond_to(:name) } 
     it { should respond_to(:questions) } 

     # Sanity check, verifying that the @section object is initially valid 
     it { should be_valid } 

    describe "Question should have one action item while persisted" do 
      pending "This is broken after changing entity relationship" 
     before { 
     @section = Section.new(name: 'Section 2') 

     linked_section = Section.new(name: 'Action Section') 
     linked_section.save 

     question = Question.new(description: 'What next?') 
     question.linked_section = linked_section 
     @section.questions << question 
     @section.save 
     . 
       . 
     . 

     } 
     . 
      . 
      . 
    end 

end 

Теперь question_spec.rb проходит без каких-либо ошибок, но получаю ActiveModel::MissingAttributeError: can't write unknown attribute 'linked_section_id' ошибку на линии question.linked_section = linked_section.

, но если вы заметили, следующие примеры question_spec.rb

it { should respond_to(:linked_section) } 
it { should respond_to(:linked_section_id) } 

проходит без каких-либо ошибок. Это означает, что у вопроса есть «linked_section_id». Так почему rspec паники?

У меня есть сомнение относительно отношения, определенного для ссылки вопроса на другой раздел. Может ли кто-нибудь помочь мне правильно спроектировать модели?

Спасибо, Амит Патель

ответ

1

Ваши данные проверяют, отвечает ли или нет вопрос к: linked_section_id (метод для чтения), не является ли или не отвечает ему: linked_section_id = (метод писателя). Все поля в таблице будут иметь связанные с ними методы чтения, и поскольку вы добавили в таблицу поле linked_section_id, существует метод чтения.

Всякий раз, когда вы добавляете внешние ключи к таблице, она должна быть * принадлежностью к * стороне ассоциации. Здесь вы использовали has_one. Переключитесь что belongs_to, и в модели Секции, положить

has_one :linked_section, :class_name => 'Question' 

Надеется, что это помогает,

+1

Спасибо Люку! Это сработало. Я действительно пропустил, что даже связанный_section_id является внешним ключом, я указал отношение как has_one, которому должно быть принадлежит_to. Также вы напомнили мне, что я проверяю метод getter, который не устанавливает его. Теперь у меня есть один вопрос. Должен ли я указывать 'has_one: linked_section,: class_name => 'Question'' в модели раздела, даже если я не хочу пересекать из раздела в вопрос? В основном я разработчик Java, и в JPA мы можем определить один к одному однонаправленные отношения. –

Смежные вопросы