我一直在尝试其他(非常)类似答案的排列,但是没有得到这个点击,我觉得我很接近。
我想以两种不同的方式将用户模型与类别模型联系起来,具体取决于用户对每个类别所需的通知渠道(文本或电子邮件)。用户可以有许多类别,反之亦然。
期望的结果:
>>@user.textcategories
=&gt; #<ActiveRecord::Associations::CollectionProxy []>
类别。
>> @user.emailcategories
=&gt; #<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 :(得分:0)
你做错了。你应该这样做:
@user.emailcategories.create! category: Category.first
@user.textcategories.create! category: Category.third
答案 1 :(得分: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
此解决方案允许您使用OP中概述的所有语法来创建/访问类别(尽管它是@user.text_categories
等,请注意下划线)