我一直在尝试在SO上排列其他(非常)类似的答案,但是还没有点击一下,我觉得我已经接近了。
我想通过两种不同的方式将用户模型与类别模型相关联,具体取决于用户希望每个类别使用哪种通知渠道(文本或电子邮件)。用户可以有许多类别,反之亦然。
期望的结果:
>>@user.textcategories
=>#<ActiveRecord::Associations::CollectionProxy []>
类别。
>> @user.emailcategories
=>#<ActiveRecord::Associations::CollectionProxy []>
类别。
>> @user.emailcategories << Category.first
>> @user.textcategories << Category.third
ETC。
当前代码:
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),得到了Category(#70239513077640)
Github克隆并尝试:https : //github.com/Grantimus9/TestRels
谢谢!
对于您现有的代码,以上答案是正确的。但是,如果要使用<<
语法,则应在联接表上使用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
该解决方案使您可以使用OP中概述的所有语法来创建/访问类别(尽管有此类@user.text_categories
,请注意下划线)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句