更新带有强参数的belongs_to关联

时间:2018-10-11 22:16:09

标签: ruby-on-rails strong-parameters

我已经使用attr_accessible很长时间了,但是我在努力适应强大的参数方面也很挣扎。

模型

class Rule
end

class Account
  belongs_to :applied_rule, class_name: 'Rule', foreign_key: 'rule_id', inverse_of: false, optional: true

  accepts_nested_attributes_for :applied_rule, update_only: true, allow_destroy: true
end

我正在尝试更新关系,但收效甚微。使用attr_accessible,您可以公开关系本身,然后使用类似@account.update(applied_rule: @rule)的东西,它将可以正常工作。

控制器

class AccountsController
  def update
    if @account.update(account_params)
      render json: AccountSerializer.new(@account)
    else
      render json: @account.errors, status: :unprocessable_entity
    end
  end

  private

  def account_params
    params.require(:account).permit(:name, applied_rule_attributes: %i(id _destroy))
  end
end

规格

RSpec.describe 'Accounts', type: :request do
  let(:account) { create(:account) }

  describe 'PUT /accounts/:id' do
    before { put account_path(account, params.merge(format: :json)) }

    let(:rule) { create(:rule) }

    context 'with good params' do
      let(:params) { { account: { applied_rule_attributes: { id: rule.id } } } }

      it { expect(response).to have_http_status(:ok) }
      it { expect(account.changed?).to be true }
      it { expect(account.applied_rule).to eq rule }
    end

    context 'when deleting relation' do
      let(:params) { { account: { applied_rule_attributes: { _destroy: true } } } }

      it { expect(response).to have_http_status(:unprocessable_entity) }
      it { expect(account.changed?).to be true }
      it { expect(account.applied_rule).to be_nil }
    end
  end
end

我最初尝试时没有嵌套属性-它仍然无法正常工作,但我感觉它的方向正确。

我想更改实体上的关系。我想将一个帐户上的适用规则设置为其他内容,或者甚至从该帐户中完全删除该适用规则(而不删除该规则,仅删除关联)。是否有惯用的方法?

有趣的代码

> params[:account][:applied_rule] = Rule.friendly.find(params[:account][:rule_id])
> params
=> <ActionController::Parameters {"account"=><ActionController::Parameters {"rule_id"=>"065230e1cb530d408e5d", "applied_rule"=>#<Rule id: 1, account_id: 3, name: "Rule 1", global: false, created_at: "2018-10-12 00:55:49", updated_at: "2018-10-12 00:55:49", slug: "065230e1cb530d408e5d">} permitted: false>, "controller"=>"accounts", "action"=>"update", "id"=>"account-2", "format"=>"json"} permitted: false>

> params.require(:account).permit(:name, :applied_rule)
=> <ActionController::Parameters {} permitted: true>

0 个答案:

没有答案