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