0

I have user model which has has_many association with building model. Initially I was creating the user and the building seperately by using user.create and user.buildings.create because there were some field in the table such that if that field is true then only it create the building and in building also there were condition that if a conditional field in building will be true then more field data will be added to the building. Everything was running smooth till a user create a single building. But when a user started to create more building it bursts the code. Below is the code of users_controller

def create
      role = Role.find_by(id: params[:user][:role_id])
      if role.nil?
        render json: { error: 'invalid role' }, status: :unprocessable_entity
      else
        user = User.new(user_params)
        user.role_id = role.id
        ActiveRecord::Base.transaction do
          if user.save
            # If the user is a technician, handle equipment_params
            if role.name.downcase == 'technician'
              equipment_ids = params[:user][:equipment_id]
              handle_technician_params(user, equipment_ids)
            end
            # If the user is a customer, handle customer_params
            if role.name.downcase == 'customer'
              handle_customer_params(user)
            end
            # Generate a new authentication token for the user
            token, refresh_token = generate_tokens(user.id)
            render json: {  message: 'User created successfully', authentication_token: token, user: user, meta: {photos: UserSerializer.new(user) }}, status: :ok
          else
            render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
          end
        end
      end
    end
def handle_customer_params(user)
      if user_params[:is_customer_direct_point_of_contact] == 'true'
        handle_building_params(user)
      else
        handle_service_params(user)
      end
    end

    def handle_building_params(user)
      building_params = params.require(:building).permit(:service_address_line1, :service_address_line2, :service_zip_code, service_images: [])
      building = user.buildings.create(building_params)
    end
    def handle_service_params(user)
      service_params = params.require(:building).permit(:service_address_line1, :service_address_line2, :service_zip_code, :name, :phone_number, :email, :tax_id, service_images: [])
      building = user.buildings.create(service_params)
    end

I tried to change it to use accepts_nested_attributes_for for direct creating the user and building but did'nt understand how to do that. Is there any also other way to do that?

1
  • I think this code could be greatly improved if you created separate controllers and routes for each type of user. The amount of cyclic complexity here is way too high. Use inheritance to avoid duplication. Commented Dec 5, 2023 at 16:17

1 Answer 1

0

There are a lot of very basic things that could be cleaned up here. These include things like testing values that should be done in the model, not the controller - user.technician? should be a model method. But to side address your specific question:

  1. Settle on a test framework
  2. Do add 'accepts_nested_attributes' to your user model
  3. Write a few request tests that add various users and building[s] until you get them right.

Do NOT experiment with functionality in the app - writing tests will make you a better coder and make the code base better and you will be able to iterate and learn faster.

https://guides.rubyonrails.org/testing.html#functional-tests-for-your-controllers

And I recommend using guard for high iteration testing: https://github.com/guard/guard

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.