Обновление относится к ассоциациям с сильными параметрами - PullRequest
0 голосов
/ 12 октября 2018

Я давно пользуюсь 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

specs

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>
...