Ruby on rails Rails 4通过关系接受嵌套的属性::\u destroy不起作用

Ruby on rails Rails 4通过关系接受嵌套的属性::\u destroy不起作用,ruby-on-rails,rspec,foreign-key-relationship,Ruby On Rails,Rspec,Foreign Key Relationship,在Rails 4.1.6应用程序中: 简短说明:当_destroy属性设置为true或1时,不会删除has_many through关系中的关联 详情: 下面描述了如何通过关系建立一个has__许多,我最终得到了以下代码: deck.rb: class Deck < ActiveRecord::Base belongs_to :beacon_owner # Beacon relationship. has_many :deck_pointers, dependent: :de

在Rails 4.1.6应用程序中:

简短说明:当_destroy属性设置为true或1时,不会删除has_many through关系中的关联

详情: 下面描述了如何通过关系建立一个has__许多,我最终得到了以下代码:

deck.rb:

class Deck < ActiveRecord::Base
  belongs_to :beacon_owner

  # Beacon relationship.
  has_many :deck_pointers, dependent: :destroy
  has_many :beacons, through: :deck_pointers

  accepts_nested_attributes_for :deck_pointers, allow_destroy: true

  # Card relationship.
  has_many :card_pointers, dependent: :destroy
  has_many :cards, through: :card_pointers

  accepts_nested_attributes_for :cards
  accepts_nested_attributes_for :card_pointers, allow_destroy: true

  validates :name, presence: true, uniqueness: true
end
我的测试是这样写的:

    it "updates the deck with fewer cards and beacons, deleting card/deck pointers" do
      deck = FactoryGirl.create :deck, name: 'Deck 1', beacon_owner_id: current_beacon_owner.id
      beacon1 = FactoryGirl.create :beacon, name: 'Beacon 1', uuid: 'abcd', beacon_owner_id: current_beacon_owner.id
      beacon2 = FactoryGirl.create :beacon, name: 'Beacon 2', uuid: 'efgh', beacon_owner_id: current_beacon_owner.id
      card1 = FactoryGirl.create :card, title: 'Card 1', beacon_owner_id: current_beacon_owner.id
      card2 = FactoryGirl.create :card, title: 'Card 2', beacon_owner_id: current_beacon_owner.id

      FactoryGirl.create :deck_pointer, deck_id: deck.id, beacon_id: beacon1.id
      FactoryGirl.create :deck_pointer, deck_id: deck.id, beacon_id: beacon2.id
      FactoryGirl.create :card_pointer, deck_id: deck.id, card_id: card1.id
      FactoryGirl.create :card_pointer, deck_id: deck.id, card_id: card2.id

      assert Deck.find_by_id(deck.id).cards.count == 2
      assert Deck.find_by_id(deck.id).beacons.count == 2
      assert CardPointer.count == 2
      assert DeckPointer.count == 2

      # TODO - why doesn't this change?
      puts '-----------------------------------------'
      puts "card pointer count: #{CardPointer.count}"
      puts "deck pointer count: #{DeckPointer.count}"
      puts "deck.cards.count: #{Deck.find_by_id(deck.id).cards.count}"
      puts "deck.beacons.count: #{Deck.find_by_id(deck.id).beacons.count}"
      puts '-----------------------------------------'

      put :update, format: :json, id: deck.id, deck: {
        name: "Updated Deck",
        card_pointers_attributes: [
          { card_id: card1.id, _destroy: true },
        ],
        deck_pointers_attributes: [
          { beacon_id: beacon1.id, _destroy: true },
          { beacon_id: beacon2.id, _destroy: true }
        ]
      }
      puts '-----------------------------------------'
      puts "card pointer count: #{CardPointer.count}"
      puts "deck pointer count: #{DeckPointer.count}"
      puts "deck.cards.count: #{Deck.find_by_id(deck.id).cards.count}"
      puts "deck.beacons.count: #{Deck.find_by_id(deck.id).beacons.count}"
      puts '-----------------------------------------'
      assert Deck.find_by_id(deck.id).cards.count == 1
      assert Deck.find_by_id(deck.id).beacons.count == 0

      assert CardPointer.count == 1
      assert DeckPointer.count == 0
   end

我在概念上误解了什么吗?我想我有允许破坏和强参数对吧。。。但可能不是,因为这是我能想到的唯一一件不正确的事情。

您可以直接删除父项,这样子项也会被删除。否则,您可以直接删除子项…例如

@user=User.first
//get any random client
client=Client.find 20
//delete child directly
@user.clients.delete(client)

此外,您需要检查父/子数据库是否都存在,因为每次测试完成后,测试数据库都会重置。

好吧,没关系,我只是手动实现了它。
class Beacon < ActiveRecord::Base
  belongs_to :beacon_owner
  has_many :deck_pointers, dependent: :destroy
  has_many :decks, through: :deck_pointers

  accepts_nested_attributes_for :deck_pointers, allow_destroy: true
  ...
end
class DeckPointer < ActiveRecord::Base
  belongs_to :beacon
  belongs_to :deck

  accepts_nested_attributes_for :beacon, reject_if: :all_blank
end
class API::V1::DecksController < API::BaseController
  before_filter :authenticate_user_from_token!, except: [:show]
  before_action :set_deck, only: [:show, :update, :destroy]
  ...
  def create
    @deck = Deck.new(deck_params)
    @deck.beacon_owner_id = current_beacon_owner.id
    @deck.save
    respond_with(@deck)
  end

  def update
    @deck.update(deck_params)
    respond_with(@deck)
  end
  ...

  private
    def set_deck
      @deck = Deck.find(params[:id])
    end

    def deck_params
      params.require(:deck).permit(:name,
        deck_pointers_attributes: [:id, :beacon_id, :deck_id, :_destroy],
        card_pointers_attributes: [:id, :card_id, :deck_id, :_destroy])
        # {deck_pointers_attributes: [:id, :beacon_id, :deck_id, :_destroy]},
        # {card_pointers_attributes: [:id, :card_id, :deck_id, :_destroy]})
    end
end
    it "updates the deck with fewer cards and beacons, deleting card/deck pointers" do
      deck = FactoryGirl.create :deck, name: 'Deck 1', beacon_owner_id: current_beacon_owner.id
      beacon1 = FactoryGirl.create :beacon, name: 'Beacon 1', uuid: 'abcd', beacon_owner_id: current_beacon_owner.id
      beacon2 = FactoryGirl.create :beacon, name: 'Beacon 2', uuid: 'efgh', beacon_owner_id: current_beacon_owner.id
      card1 = FactoryGirl.create :card, title: 'Card 1', beacon_owner_id: current_beacon_owner.id
      card2 = FactoryGirl.create :card, title: 'Card 2', beacon_owner_id: current_beacon_owner.id

      FactoryGirl.create :deck_pointer, deck_id: deck.id, beacon_id: beacon1.id
      FactoryGirl.create :deck_pointer, deck_id: deck.id, beacon_id: beacon2.id
      FactoryGirl.create :card_pointer, deck_id: deck.id, card_id: card1.id
      FactoryGirl.create :card_pointer, deck_id: deck.id, card_id: card2.id

      assert Deck.find_by_id(deck.id).cards.count == 2
      assert Deck.find_by_id(deck.id).beacons.count == 2
      assert CardPointer.count == 2
      assert DeckPointer.count == 2

      # TODO - why doesn't this change?
      puts '-----------------------------------------'
      puts "card pointer count: #{CardPointer.count}"
      puts "deck pointer count: #{DeckPointer.count}"
      puts "deck.cards.count: #{Deck.find_by_id(deck.id).cards.count}"
      puts "deck.beacons.count: #{Deck.find_by_id(deck.id).beacons.count}"
      puts '-----------------------------------------'

      put :update, format: :json, id: deck.id, deck: {
        name: "Updated Deck",
        card_pointers_attributes: [
          { card_id: card1.id, _destroy: true },
        ],
        deck_pointers_attributes: [
          { beacon_id: beacon1.id, _destroy: true },
          { beacon_id: beacon2.id, _destroy: true }
        ]
      }
      puts '-----------------------------------------'
      puts "card pointer count: #{CardPointer.count}"
      puts "deck pointer count: #{DeckPointer.count}"
      puts "deck.cards.count: #{Deck.find_by_id(deck.id).cards.count}"
      puts "deck.beacons.count: #{Deck.find_by_id(deck.id).beacons.count}"
      puts '-----------------------------------------'
      assert Deck.find_by_id(deck.id).cards.count == 1
      assert Deck.find_by_id(deck.id).beacons.count == 0

      assert CardPointer.count == 1
      assert DeckPointer.count == 0
   end
@user=User.first
//get any random client
client=Client.find 20
//delete child directly
@user.clients.delete(client)