0

I have this setup.

A user has many clinics, and a clinic has many practitioners. Clinics belongs to user and practitioners belongs to clinic.

I’m using wicked wizard for the sign up. These are the steps: user info, clinic info, practitioner info.

After the sign up, the user should be able to add more practitioners to the clinic, but I’m not sure how to do that.

I have an overview page, where I will list all the practitioners that are attached to that specific clinic, and there is also an add new practitioner link, which when clicked, should start the practitioner info sign up step for a new practitioner and associate the practitioner to the clinic.

I guess it’s pretty simple, but I just don’t understand how to do it. Tried to search google, but I can’t find an explanation on how to do this.

When I click add new practitioner I'll get to the practitioner sign up form, but when I hit sumbit, I get this error

undefined method `practitioners' for nil:NilClass

user.rb

class User < ApplicationRecord
  has_many :services, dependent: :destroy
  accepts_nested_attributes_for :services, reject_if: :all_blank, allow_destroy: true

  has_many :educations, dependent: :destroy
  accepts_nested_attributes_for :educations, reject_if: :all_blank, allow_destroy: true

  has_many :awards, dependent: :destroy
  accepts_nested_attributes_for :awards, reject_if: :all_blank, allow_destroy: true

  has_many :user_professions, dependent: :destroy
  has_many :professions, through: :user_professions

  has_many :user_memberships, dependent: :destroy
  has_many :memberships, through: :user_memberships

  has_many :user_specialities, dependent: :destroy
  has_many :specialities, through: :user_specialities

  has_many :clinics, dependent: :destroy
  accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true


  has_one_attached :clinic_logo
  accepts_nested_attributes_for :clinic_logo_attachment, allow_destroy: true

  has_one_attached :practitioner_image
  has_many_attached :clinic_images

  # Note that implicit association has a plural form in this case
  scope :with_eager_loaded_images, -> { eager_load(images_attachments: :blob) }
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :validatable

  after_create :send_admin_mail

  def send_admin_mail
    UserMailer.send_welcome_email(self).deliver_later
  end
end

clinic.rb

class Clinic < ApplicationRecord 
  belongs_to :user 
  has_many :practitioners, dependent: :destroy
  accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
end

practitioner.rb

class Practitioner < ApplicationRecord
  belongs_to :clinic

  def current_step?(step_key) 
    current_step == step_key 
  end

  enum practitioner_gender: { Mand: 0, Kvinde: 1 }

  def self.genders_for_select
    practitioner_genders.keys.map{ |x| [x.humanize, x] }
  end
end

userprofiles/practitioners.html.erb
This is the page where I list all practitioners and the user should be able to click the add new practitioner button.

<div class="app-container partner-wrapper clinic-wrapper practitioner-list-wrapper">
    <div class="page">
        <div class="tabs-container">
            <ul class="tabs">
                <li class="">
                    <a class="btn transparent" href="/userprofiles/clinic_info">
                        <span class=" flex">Klinikoplysninger</span>
                    </a>
                </li>
                <li class="">
                     <a class="btn transparent active" href="/userprofiles/practitioners">
                        <span class="flex">Behandlere</span>
                    </a>
                </li>
            </ul>
        </div>

        <div class="content-container">
            <div class="content practitioners">
                <ul class="practitioners">
                    <li class="practitioner"><a class="overlay"></a>
                        <div class="image">
                            <% if @current_user.clinic_logo.attached? %>
                            <%= image_tag @current_user.clinic_logo.variant(resize: "100x100")%>
                            <% else %>
                            <div class="image"
                                style="background-image: url(&quot;https://betterwing.s3.amazonaws.com/images/default-practitioner.png&quot;);">
                            </div>
                            <% end %>
                            <%= link_to (@current_user.first_name), practitioner_info_path(@current_user) %>
                        </div>

                        <h4 class="name">sdad sad</h4>
                        <div class="btn-container delete">
                            <button class="btn pink" type="button">
                                <span class="flex"><i class="material-icons icon ">delete</i></span>
                            </button>
                        </div>
                    </li>

                    <li class="AddPractitioner">
                        <%= link_to [:new], class: 'overlay' do %>
                          <div class="image">
                            <i class="material-icons icon ">add</i>
                          </div>
                        <% end %>
                        <h4 class="name">Add new practitioner</h4>
                    </li>

                </ul>
            </div>
        </div>
    </div>
</div>

routes.rb

Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  devise_for :users, controllers: {:registrations => "users/registrations" }

  resources :registration_steps
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  root 'pages#index' 
  get 'about', to: 'pages#about'
  get 'team', to: 'pages#team'
  get 'faqs', to: 'pages#faqs'
  get 'faqspractitioners', to: 'pages#faqspractitioners'
  get 'faqsusers', to: 'pages#faqsusers'
  get 'login', to: 'pages#login'
  get 'signup', to: 'pages#signup'
  get 'search', to: 'pages#search'
  get 'practitioner', to: 'pages#practitioner'

  get "userprofiles/user_info" => "userprofiles#user_info", as: "user_info"
  get "userprofiles/clinic_info" => "userprofiles#clinic_info", as: "clinic_info"
  get "userprofiles/practitioner_info" => "userprofiles#practitioner_info", as: "practitioner_info"
  get "userprofiles/practitioners" => "userprofiles#practitioners", as: "practitioners"

  patch "userprofiles/user_info" => "userprofiles#update"
  patch "userprofiles/clinic_info" => "userprofiles#update"
  patch "userprofiles/practitioner_info" => "userprofiles#update"

  resources :clinics do 
    resources :practitioners
  end

  devise_scope :user do 
    scope module: :users do
      resources :registrations, only: [] do
        member do
          delete :delete_image_attachment
        end
      end
    end
  end
end
**userprofiles_controller.rb**

class UserprofilesController < ApplicationController

  def new
    @practitioner = @clinic.practitioners.new
  end


  def clinic_info
    @user = current_user     
  end


  def practitioner_info
    @user = current_user
  end

  def practitioners
    @user = current_user
  end

  def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end

  private
  def user_params
    params.require(:user)
    .permit(:first_name, :last_name, :email, :password, :password_confirmation, :phone, 
      :clinic_logo, 
      :practitioner_image, 
      clinic_images: [], 
      profession_ids: [], 
      speciality_ids: [], 
      services_attributes: [:id, :description, :name, :duration, :price, :_destroy], 
      educations_attributes: [:id, :name, :place, :year, :_destroy],
      membership_ids: [],
      awards_attributes: [:id, :name, :year, :_destroy],
      clinics_attributes: [:id, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy,
      practitioners_attributes: [:id, :public_health_insurance, :practitioner_gender, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])

  end

end

userprofiles/new.html.erb

        <div id="PractitionerGenerel" class="TabBlock">
          <div class="content">
            <div class="content practitioner">
              <h2 class="page-title">Generel information</h2>
              <%= simple_form_for [@clinic, @practitioner] do |f| %>
                <%= f.simple_fields_for(:clinics) do |p| %>
                  <%= render 'clinics/clinic-practitioners-fields', :f => p %>
                <% end %>
                <div class="submit-container">
                  <%= f.submit "Gem", :class => 'btn blue'  %>
                </div>
              <% end %>
            </div>
          </div>
        </div>

Log

Started GET "/userprofiles/new" for ::1 at 2020-03-04 21:21:52 +0100
   (2.8ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
  ↳ /Users/kaspervalentin/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/activerecord-5.2.4.1/lib/active_record/log_subscriber.rb:98
Processing by UserprofilesController#new as HTML
  Rendering userprofiles/new.html.erb within layouts/application
  Rendered practitioners/_practitioners_fields.html.erb (19.4ms)
  Rendered clinics/_clinic-practitioners-fields.html.erb (23.8ms)
  User Load (2.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 96 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ app/views/userprofiles/new.html.erb:65
  Profession Load (0.8ms)  SELECT `professions`.* FROM `professions` INNER JOIN `user_professions` ON `professions`.`id` = `user_professions`.`profession_id` WHERE `user_professions`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:69
  Profession Load (0.5ms)  SELECT `professions`.* FROM `professions`
  ↳ app/views/userprofiles/new.html.erb:69
  Speciality Load (0.5ms)  SELECT `specialities`.* FROM `specialities` INNER JOIN `user_specialities` ON `specialities`.`id` = `user_specialities`.`speciality_id` WHERE `user_specialities`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:84
  Speciality Load (0.7ms)  SELECT `specialities`.* FROM `specialities`
  ↳ app/views/userprofiles/new.html.erb:84
  Service Load (0.4ms)  SELECT `services`.* FROM `services` WHERE `services`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:97
  Rendered services/_services_fields.html.erb (9.5ms)
  Rendered services/_services_fields.html.erb (6.0ms)
  Education Load (0.4ms)  SELECT `educations`.* FROM `educations` WHERE `educations`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:134
  Rendered educations/_educations_fields.html.erb (10.2ms)
  Rendered educations/_educations_fields.html.erb (4.3ms)
  Rendered educations/_educations_fields.html.erb (5.8ms)
  Membership Load (2.5ms)  SELECT `memberships`.* FROM `memberships` INNER JOIN `user_memberships` ON `memberships`.`id` = `user_memberships`.`membership_id` WHERE `user_memberships`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:156
  Membership Load (0.4ms)  SELECT `memberships`.* FROM `memberships`
  ↳ app/views/userprofiles/new.html.erb:156
  Award Load (0.4ms)  SELECT `awards`.* FROM `awards` WHERE `awards`.`user_id` = 96
  ↳ app/views/userprofiles/new.html.erb:168
  Rendered awards/_awards_fields.html.erb (5.5ms)
  Rendered awards/_awards_fields.html.erb (72.6ms)
  Rendered userprofiles/new.html.erb within layouts/application (369.2ms)
  Rendered layouts/_header.html.erb (6.5ms)
  Rendered layouts/_footer.html.erb (1.6ms)
Completed 200 OK in 537ms (Views: 334.8ms | ActiveRecord: 145.4ms)


Started POST "/userprofiles/practitioners" for ::1 at 2020-03-04 21:23:25 +0100

ActionController::RoutingError (No route matches [POST] "/userprofiles/practitioners"):

actionpack (5.2.4.1) lib/action_dispatch/middleware/debug_exceptions.rb:65:in `call'
web-console (3.7.0) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.7.0) lib/web_console/middleware.rb:30:in `block in call'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `catch'
web-console (3.7.0) lib/web_console/middleware.rb:20:in `call'
actionpack (5.2.4.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (5.2.4.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (5.2.4.1) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (5.2.4.1) lib/active_support/tagged_logging.rb:71:in `block in tagged'
activesupport (5.2.4.1) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (5.2.4.1) lib/active_support/tagged_logging.rb:71:in `tagged'
railties (5.2.4.1) lib/rails/rack/logger.rb:26:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.2.4.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (5.2.4.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.1.1) lib/rack/method_override.rb:24:in `call'
rack (2.1.1) lib/rack/runtime.rb:24:in `call'
activesupport (5.2.4.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (5.2.4.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (5.2.4.1) lib/action_dispatch/middleware/static.rb:127:in `call'
rack (2.1.1) lib/rack/sendfile.rb:113:in `call'
railties (5.2.4.1) lib/rails/engine.rb:524:in `call'
puma (3.12.2) lib/puma/configuration.rb:227:in `call'
puma (3.12.2) lib/puma/server.rb:674:in `handle_request'
puma (3.12.2) lib/puma/server.rb:476:in `process_client'
puma (3.12.2) lib/puma/server.rb:334:in `block in run'
puma (3.12.2) lib/puma/thread_pool.rb:135:in `block in spawn_thread'
kvnirvana
  • 71
  • 1
  • 8

1 Answers1

0

I have a few questions as follow up.

  1. Why do you have href="/partner/practitioners/5e289036c3bbe8770f417830" ?
  2. Not sure how your code is working or not working because
<li class="AddPractitioner">
  <a class="overlay" href="/partner/practitioners/new"></a>
  <div class="image">
    <i class="material-icons icon ">add</i>
  </div>
  <h4 class="name">Add new practitioner</h4>
</li>

Will not display any link may be you should change it to

<li class="AddPractitioner">
  <%= link_to [:partner, :practitioners, :new], class: 'overlay' do %>
    <div class="image">
      <i class="material-icons icon ">add</i>
    </div>
  <% end %>
  <h4 class="name">Add new practitioner</h4>
</li>

** Update **

<%= simple_form_for @practitioner, url: new_path do |f| %>, you should not direct it to url: new_path.

If you are are creating a new practitioner for a clinic routes should be

resources :clinics do 
 resources :practitioners
end

and the form should look like

<div id="PractitionerGenerel" class="TabBlock">
  <div class="content">
    <div class="content practitioner">
      <h2 class="page-title">Generel information</h2>
      <%= simple_form_for [@clinic, @practitioner] do |f| %>
        <%= f.simple_fields_for(:clinics) do |p| %>
          <%= render 'clinics/clinic-practitioners-fields', :f => p %>
        <% end %>
        <div class="submit-container">
          <%= f.submit "Gem", :class => 'btn blue'  %>
        </div>
      <% end %>
    </div>
  </div>
</div>

Also, see your opening and closing tags should match. More read at

Sahil Grover
  • 1,862
  • 4
  • 26
  • 57
  • href="/partner/practitioners/5e289036c3bbe8770f417830" was a mistake, it was some old code, it has been removed now. I've updated the code and also added userprofiles_controller where the new method is defined, and new.html.erb where the form is located, but I'm not sure where to go from here. When I click the link, I see the sign up form, but when I fill it out and hit submit I get a routing error. – kvnirvana Mar 04 '20 at 07:28
  • Thank you for the links and your help, appreciate it very much. I'll go through the links to learn more about these topics. I've updated the code, but I still get the routing error – kvnirvana Mar 04 '20 at 14:56