My shop model with accepts_nested_attributes_for
class Shop < ApplicationRecord
has_many :open_slots, dependent: :delete_all
validates :name, presence: true
belongs_to :user
accepts_nested_attributes_for :open_slots
end
schema file :
ActiveRecord::Schema[7.0].define(version: 20_230_923_091_441) do
# These are extensions that must be enabled in order to support this database
enable_extension 'plpgsql'
create_table 'open_slots', force: :cascade do |t|
t.integer 'day_number'
t.time 'start_time'
t.time 'end_time'
t.bigint 'shop_id', null: false
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.index ['shop_id'], name: 'index_open_slots_on_shop_id'
end
create_table 'shops', force: :cascade do |t|
t.string 'name'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.bigint 'user_id', null: false
t.index ['user_id'], name: 'index_shops_on_user_id'
end
create_table 'users', force: :cascade do |t|
t.string 'email', default: '', null: false
t.string 'encrypted_password', default: '', null: false
t.string 'reset_password_token'
t.datetime 'reset_password_sent_at'
t.datetime 'remember_created_at'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.string 'authentication_token', limit: 30
t.index ['authentication_token'], name: 'index_users_on_authentication_token', unique: true
t.index ['email'], name: 'index_users_on_email', unique: true
t.index ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true
end
add_foreign_key 'open_slots', 'shops'
end
ShopsController where I permit open_slots_attributes
module Api
module V1
class ShopsController < BaseController
acts_as_token_authentication_handler_for User, except: %i[index show]
def create
@shop = Shop.new(shop_params)
@shop.user = current_user
authorize @shop
if @shop.save
@presenter = ::ShowShopPresenter.new(@shop.id)
render :show, status: :created
else
render_error
end
end
private
def render_error
render json: { errors: @shop.errors.full_messages },
status: :unprocessable_entity
end
def shop_params
params.require(:shop).permit(:name, open_slots_attributes: [:day_number, :start_time, :end_time])
end
end
end
end
With postman, is create Shop and open slots without problem. But when i run specs, it create only shop and not open slots
spec file :
describe 'POST/create' do
let!(:user) { create(:user) }
let(:valid_params) do
{
"shop":
{
name: name
}
}
end
let(:name) {}
subject(:create_shop) { post '/api/v1/shops', params: valid_params }
context 'when user is sign in' do
before do
sign_in user
end
context 'and name is missing' do
it 'return error' do
create_shop
expect(response.status).to eq 422
expect(JSON.parse(response.body)['errors']).to include("Name can't be blank")
end
end
context 'and name is right' do
let(:name) { 'test name' }
it 'returns status code 201' do
create_shop
expect(response.status).to eq 201
end
it 'create new shop' do
expect { create_shop }.to change { Shop.count }.by(1)
end
context 'and when valid open_slots_attribute are present' do
before do
valid_params["open_slots_attributes"] =
{
"start_time": "12:30",
"end_time": "18:30",
"day_number": 1
},
{
"start_time": "12:30",
"end_time": "18:30",
"day_number": 2
},
{
"start_time": "12:30",
"end_time": "18:30",
"day_number": 6
}
end
it 'create open slots for shop' do
expect { create_shop }.to change { OpenSlot.count }.by(3)
end
end
end
end
context 'when user is not sign in' do
let(:name) { 'test name' }
it 'return authentication error' do
create_shop
expect(response.status).to eq 401
end
end
end
the error :
1) Shops POST/create when user is sign in and name is right and when valid open_slots_attribute are present create open slots for shop Failure/Error: expect { create_shop }.to change { OpenSlot.count }.by(3) expected OpenSlot.countto have changed by 3, but was changed by 0 # ./spec/api/v1/shops_controller_spec.rb:137:inblock (6 levels) in <top (required)>'`
i tried to allow shop_params in the before but it didn't work
Change
valid_params["open_slots_attributes"]tovalid_params["shop"]["open_slots_attributes"]