2014-11-30 2 views
1

У меня возникли проблемы с отношениями в Rails 4.has_one belongs_to вопрос отношения в Rails 4

Есть 4 модели

  1. Пользователь
  2. Запрос
  3. Сделать
  4. Модели

Пользователь has_many Запросы, запрос имеет _one Make и Make has_many Модели.

User-> Requests and Make-> Models has_many отношения прекрасны, но связь Request-> Make has_one не выполняется.

class Request < ActiveRecord::Base 
    belongs_to :user 
    has_one :make 
end 

class Make < ActiveRecord::Base 
    has_many :models 
    belongs_to :request 
end 

Схемы для каждой модели ...

create_table "requests", force: true do |t| 
    t.integer "user_id" 
    t.integer "make_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

create_table "makes", force: true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

При попытке назначить Марк на запрос я получаю следующую ошибку

Mysql2::Error: Unknown column 'makes.request_id' in 'where clause': SELECT `makes`.* FROM `makes` WHERE `makes`.`request_id` = 7 LIMIT 1                   
ActiveRecord::StatementInvalid Exception: Mysql2::Error: Unknown column 'makes.request_id' in 'where clause': SELECT `makes`.* FROM `makes` WHERE `makes`.`request_id` = 7 LIMIT 1         
nil 

Почему ActiveRecord, требующей request_id в Make? Разве это не применимо только для отношений has_many, как у меня в отношениях User-> Requests and Makes-> Models?

ответ

3

has_one В и belongs_to методы позволяют создавать один-к-одному ассоциации между вашими моделями, поэтому позволяет легко получить доступ друг с другом с помощью различных вспомогательных методов.

has_one следует использовать только в том случае, если другой класс содержит «внешний ключ». Если текущий класс содержит «внешний ключ», вместо этого вы должны использовать belongs_to.

Основываясь на схеме предоставленной вами ассоциации должны быть определены, как в следующем примере:

class Request < ActiveRecord::Base 
    # Because you have a `make_id` column in the "requests" table. 
    belongs_to :make 
end 

class Make < ActiveRecord::Base 
    # Because the Request model has the "foreign key" that 
    # creates the association, in this case `make_id`. 
    has_one :request 
end 

Производя ассоциаций, как в приведенном выше примере, Rails предоставит вам вспомогательные методы, которые позволяют вам доступ или создание каждой связанный с ним модель:

# Request Model 
@request = Request.create! 

# Helper methods to access `make`: make, build_make, create_make, make= 
@request.make 
@request.build_make 
@request.create_make 
@request.make = Make.create! 
# ... 


# Make Model 
@make = Make.create! 

# Helper methods to access `request` 
@make.request 
@make.build_request 
@make.create_request 
@make.request = Request.create! 
#... 

Мы используем has_one и belongs_to метод для создания ассоциаций, но и иметь доступ ко всем вспомогательным методам, которые Rails создает для нас.В зависимости от того, хотите ли вы получить доступ к Марка из запроса или наоборот, вы можете добавить или удалить HAS_ONE или belongs_to из определенного класса.

Сохраняя каждый в обоих классах, мы получаем доступ к набору вспомогательных методов с обеих сторон. Если, например, вы удалили belongs_to :make из Запроса, вы не смогли бы получить сделать с запросом с @request.make. Тем не менее, вы все равно можете получить запрос от make с помощью @make.request до тех пор, пока вы сохраняете метод has_one.

Помните, что миграция - это их собственная вещь, и нам также необходимо настроить ассоциации на уровне базы данных, добавив «внешний ключ» в правильную таблицу. Мы можем легко определить, где добавить внешний ключ, просмотрев определения has_one и принадлежит_от. has_one говорит, что «внешний ключ» должен быть в связанной таблице, а принадлежит_от говорит, что он должен быть в этой таблице.

Я надеюсь, что это поможет! Существует еще некоторая информация здесь:

+0

Спасибо за вашу помощь! Вы были правы, так как ассоциация была неправильной. Я искал отношения друг к другу, поэтому у меня есть has_many на стороне Make, а не has_one. –

0

Основываясь на вашей схеме и сообщении об ошибке, по-видимому, нет внешнего ключа от requests в makes.

Смотрите это, например:

http://guides.rubyonrails.org/association_basics.html#the-has-one-association

Там, Поставщик имеет один счет, и accounts имеет supplier_id. Проверьте соответствующий пример миграции.

0

Вы, наверное, просто нужно добавить столбец REQUEST_ID к столу делает.

Пробег:

rails g migration add_request_id_to_makes request_id:integer 


bundle exec rake db:migrate 
Смежные вопросы