Ассоциация в rails не работает

#mysql #ruby-on-rails #activerecord #join #ruby-on-rails-4

#mysql #ruby-on-rails #activerecord #Присоединиться #ruby-on-rails-4

Вопрос:

У меня немного сложный дизайн модели со многими ассоциациями между собой. Вот дизайн модели

Пользовательская модель

 class User < ActiveRecord::Base
has_many :records
has_many :sources
has_many :record_type_student
has_many :record_type_employee
has_many :record_type_other

validates :email, presence: true

end
 

Модель Souces

 class Source < ActiveRecord::Base

belongs_to :user

 has_many :records
 has_many :record_type_student
 has_many :record_type_employee
 has_many :record_type_other

end
 

Модель записи

 class Record < ActiveRecord::Base
 belongs_to :user
 belongs_to :source

 has_many :record_type_student
 has_many :record_type_employee
 has_many :record_type_other

end
 

Модель RecordTypeStudent

   class RecordTypeStudent < ActiveRecord::Base
   belongs_to :record
 belongs_to :user
belongs_to :source

end
 

Аналогичная модель для двух других RecordTypeOther и RecordTypeEmployee

Я могу правильно сохранять данные, и я проверил, что каждая recordtype* таблица содержит в ней record_id, и теперь я пытаюсь получить доступ к данным с помощью includes . Вот что я пытаюсь запросить

  @records = Record.includes(:record_type_stduents, :record_type_others, :record_type_employees).where(User.find_by_email(params[:user].to_s).id).all;
 

но я получаю только поля записей взамен, а не данные после присоединения

Здесь генерируется запрос

  Record Load (1.9ms)  SELECT `records`.* FROM `records` WHERE `records`.`user_id` =  1    RecordTypeStudent Load (7.9ms)  SELECT `record_type_students`.* FROM  `record_type_students` WHERE `record_type_students`.`record_id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)  RecordTypeOther Load (2.4ms)  SELECT `record_type_others`.* FROM `record_type_students`    WHERE `record_type_students`.`record_id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)  RecordTypeEmployee Load (2.0ms)  SELECT `record_type_employees`.* FROM `record_type_employees` WHERE `record_type_employees`.`recordt_id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)
 

Вот когда я пытаюсь извлечь из пользовательской модели

 DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`). (called from irb_binding at (irb):15)

User Load (3.4ms)  SELECT `users`.* FROM `users` INNER JOIN `records` ON `records`.`user_id` = `users`.`id` WHERE `users`.`user_id` = 1
 

Mysql :: Ошибка: неизвестный столбец ‘users.user_id’ в ‘предложении where’: ВЫБЕРИТЕ users .* ИЗ users ВНУТРЕННЕГО СОЕДИНЕНИЯ records НА records . user_id = users . id WHERE users . user_id = 1 ActiveRecord::StatementInvalid: Mysql :: Ошибка: неизвестный столбец ‘users.user_id’ в ‘предложении where’: ВЫБЕРИТЕ users .* ИЗ users ВНУТРЕННЕГО СОЕДИНЕНИЯ . = . WHERE . = 1 ActiveRecord::StatementInvalid:ПРИСОЕДИНИТЬСЯ records К records . user_id = users . id WHERE users . user_id = 1

Комментарии:

1. among themselves — вы имели в виду self referential объединения?

2. нет, ассоциации, подобные тем, о которых я упоминал в каждой модели, не содержат ссылок на себя

3. но вы получили проблему в коде или я недостаточно хорошо объяснил здесь…

4. Просто ищу тебя сейчас!

5. я думаю, что проблема в запросе. не могли бы вы вставить сгенерированный SQL-запрос?

Ответ №1:

Я думаю, вам лучше всего использовать STI (наследование одной таблицы):

 #app/models/user.rb
Class User < ActiveRecord::Base
   has_many :students, class: "User::Student"
   has_many :employees, class: "User::Employee"
   has_many :other, class: "User::Other"
end

#app/models/users/student.rb
Class Student < Record
end

#app/models/record.rb
Class Record < ActiveRecord::Base
   belongs_to :user
end
 

Это даст вам следующие поля:

 #users
id | user | attributes | created_at | updated_at

#records
id | type | user_id | other | record | attributes | created_at | updated_at
 

Это позволит вам вызвать:

 user = User.find params[:id]
user.students # -> pulls records with type == "Student"
 

Комментарии:

1. Большое спасибо, я попробую это и сообщу вам, как это работает, но у одного ученика, у другой модели etc не будет никакой ассоциации, определенной в них

2. Я не думаю, что им это понадобится (хотя я могу ошибаться). STI в основном наследуется от родительских моделей; это означает, что вы должны иметь возможность сохранять центральную ассоциацию; хотя я могу ошибаться в этом

3. Один вопрос, я читал о STI, но не мог понять, как создавать модели, такие как Student, которые наследуются от Record … любая команда или как я бы добавил поля в модель student

4. Извините, я обновлю свой ответ для вас! Здесь есть отличный учебник: rails-bestpractices.com/posts /…