Rails。通过嵌套属性设置多对多关系

Rails. Many to many set relation via nested attributes

我一直在尝试弄清楚如何使用嵌套属性设置 has_many, through: 关系。

我有以下型号:

user.rb

class User < ApplicationRecord
   has_many :user_tags
   has_many :tags, through: :user_tags

   accepts_nested_attributes_for :user_tags,
                            allow_destroy: true,
                            reject_if: :all_blank
end

user_tag.rb

class UserTag < ApplicationRecord
  belongs_to :tag
  belongs_to :user

  accepts_nested_attributes_for :tag

  validates :tag, :user, presence: true
  validates :tag, :uniqueness => {:scope => :user}
  validates :user, :uniqueness => {:scope => :tag}
end

tag.rb

class Tag < ApplicationRecord
  has_many :user_tags
  has_many :users, through: :user_tags

  validates :title, presence: true, uniqueness: true
end

相关架构

  create_table "user_tags", id: :integer, force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "tag_id"
    t.index ["tag_id"], name: "index_user_tags_on_tag_id", using: :btree
    t.index ["user_id"], name: "index_user_tags_on_user_id", using: :btree
  end

  create_table "tags", id: :integer, force: :cascade do |t|
    t.string   "title"
    t.string   "language"
    t.integer  "type"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

所有标签都是预定义的,不能修改。 我只需要通过嵌套属性在用户的 create/update 操作中设置和销毁模型 user_tagtagsusers 之间的关系。

类似于:

params = { user: {
      user_tags_attributes: [
          { id: 1, _destroy: '1' }, # this will destroy association
          { tag_id: 1 }, # this will create new association with tag, which id=1 if tag present
          { tag_title: 'name' } # this will create new association with tag, which title='name' if tag present
      ]
  }}

user.update_attributes(params[:user])

确切的问题是我无法创建 ONYL 关联,但我可以通过关联创建或更新标签。

我正在使用 Rails 5.0

我找到了解决问题的方法。我在 UserTag 验证中有错误。

我变了

  validates :tag, :uniqueness => {:scope => :user}
  validates :user, :uniqueness => {:scope => :tag}

  validates :tag_id, :uniqueness => {:scope => :user_id}
  validates :user_id, :uniqueness => {:scope => :tag_id}

标签分配正常。

需要找到如何通过 tag_id,没有关联 ID

来破坏关联的解决方案