0

I am using Rspec to test a controller that received nested_attributes. A class Option can has_many Suboptions.

models/suboption.rb:

class Suboption < ApplicationRecord
  belongs_to :option,
  optional: true

  validates :name, presence: true
end

models/option.rb:

class Option < ApplicationRecord
  belongs_to :activity
  has_many :suboptions, dependent: :destroy

  accepts_nested_attributes_for :suboptions, allow_destroy: true,

    reject_if: ->(attrs) { attrs['name'].blank? }

  validates :name, presence: true
end

Params:

def option_params
    params.require(:option).permit(:name, :activity_id, :students_ids => [], suboptions_attributes: [:id, :name, :_destroy])
  end

spec/controller/options_controller_spec.rb:

describe "POST #create" do
        let(:option) { assigns(:option) }
        let(:child) { create(:suboption) }

        context "when valid" do
          before(:each) do
            post :create, params: {
              option: attributes_for(
                :option, name: "opt", activity_id: test_activity.id,
                suboptions_attributes: [child.attributes]
              )
            }
          end

          it "should redirect to options_path" do
            expect(response).to redirect_to options_path
          end

          it "should save the correctly the suboption" do
            expect(option.suboptions).to eq [child]
          end
        end

Testing Post, I would like to ensure that option.suboptions to be equal to [child]. But I don't know how to pass the attributes of the instance child to suboptions_attributes. This way that I did is not working.

1 Answer 1

2

Found the answer:

describe "POST #create" do
    let(:option) { assigns(:option) }

    context "when valid" do
      before(:each) do
        post :create, params: {
          option: attributes_for(:option, name: "opt", activity_id: test_activity.id,
            suboptions_attributes: [build(:option).attributes]
          )
        }
      end

      it "should save suboptions" do
        expect(option.suboptions.first).to be_persisted
        expect(Option.all).to include option.suboptions.first
      end

      it "should have saved the same activity_id for parent and children" do
        expect(option.suboptions.first.activity_id).to eq option.activity_id
      end
    end

This is a way of doing it.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.