2015-06-08 3 views
0

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

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

Желаемый результат:

>>@user.textcategories =>#<ActiveRecord::Associations::CollectionProxy []> Категорий.

>> @user.emailcategories =>#<ActiveRecord::Associations::CollectionProxy []> Категории.

>> @user.emailcategories << Category.first

>> @user.textcategories << Category.third т.д.

Текущий код:

class User < ActiveRecord::Base 
    has_many :emailcategories 
    has_many :categories, through: :emailcategories 

    has_many :textcategories 
    has_many :categories, through: :textcategories 
end 

class Category < ActiveRecord::Base 
    has_many :emailcategories 
    has_many :users, through: :emailcategories 

    has_many :textcategories 
    has_many :users, through: :textcategories 
end 

class Emailcategory < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :category 
end 

class Textcategory < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :category 
end 

Миграция/схема:

create_table "emailcategories" do |t| 
     t.integer :user_id 
     t.integer :category_id 
     t.datetime "created_at",  null: false 
     t.datetime "updated_at",  null: false 
    end 

    create_table "textcategories" do |t| 
     t.integer :user_id 
     t.integer :category_id 
     t.datetime "created_at",  null: false 
     t.datetime "updated_at",  null: false 
    end 

    create_table :users do |t| 
     t.string :name 
    end 

    create_table :categories do |t| 
     t.string :name 
    end 

Текущее сообщение об ошибке: >> @user.emailcategories << Category.first ActiveRecord :: AssociationTypeMismatch: Emailcategory (# 70239513207200) ожидается, получил Категория (# 70239513077640)

Github клонировать и попробовать: https://github.com/Grantimus9/TestRels

Спасибо!

ответ

0

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

# db/schema.rb 
create_table "categories", force: :cascade do |t| 
    t.string "name" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

create_table "category_users", force: :cascade do |t| 
    t.integer "category_id" 
    t.integer "user_id" 
    t.string "type" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

create_table "users", force: :cascade do |t| 
    t.string "name" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
end 

# app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :email_category_users 
    has_many :email_categories, through: :email_category_users, source: :category 
    has_many :text_category_users 
    has_many :text_categories, through: :text_category_users, source: :category 

    # If you also need to get all categories on a user 
    has_many :category_users 
    has_many :categories, through: :category_users 
end 

# app/models/category_user.rb 
class CategoryUser < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :category 
end 

# app/models/email_category_user.rb 
class EmailCategoryUser < CategoryUser 
end 

# app/models/text_category_user.rb 
class TextCategoryUser < CategoryUser 
end 

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_many :category_users 
    has_many :users, through: :category_users 
end 

Это решение позволяет использовать весь синтаксис, изложенной в ОП для создания/категорий доступа (хотя это @user.text_categories и т.д., обратите внимание на подчеркивание)

+0

Это путь - это позволяет мне легко добавлять новые отношения между двумя моделями в будущем, расширяя категорию так же, как, например, E-MailCategoryUser расширяет CategoryUser. –

0

Вы сделали это неправильно. Вы должны сделать следующее:

@user.emailcategories.create! category: Category.first 
@user.textcategories.create! category: Category.third 
Смежные вопросы