Создать действие - ActiveModel :: ForbiddenAttributesError - PullRequest
0 голосов
/ 09 марта 2020

Я пытаюсь создать клинику, связанную с current user. Но когда я нажимаю «отправить», я получаю эту ошибку. Я использую devise, rails admin и cancancan. Я не знаю, могло ли это быть причиной ошибки или что-то еще не так.

ActiveModel :: ForbiddenAttributesError в ClinicsController # create ActiveModel :: ForbiddenAttributesError

user. руб

class User < ApplicationRecord

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

end

клини c .rb

class Clinic < ApplicationRecord  

    belongs_to :user   

end

clinics_controller.rb

class ClinicsController < ApplicationController
    before_action :set_clinic, only: [:show, :edit, :update, :destroy]

    def index
        @clinic = Clinic.all      
        @user = current_user
     end

     def show
        @clinic = Clinic.find(params[:id])
        @user = current_user
     end

     def edit
        @clinic = Clinic.find(params[:id])
     end


    def new
        @clinic = current_user.clinics.new
    end

    def create
        @clinic = current_user.clinics.new(params[:clinic])

        respond_to do |format|
          if @clinic.save
            format.html { redirect_to @clinic, notice: 'Clinic was successfully created.' }
            format.json { render :show, status: :created, location: @clinic }
          else
            format.html { render :new }
            format.json { render json: @clinic.errors, status: :unprocessable_entity }
          end
        end
      end


      def update
        respond_to do |format|
          if @clinic.update(params[:clinic])
            format.html { redirect_to @clinic, notice: 'Clinic was successfully updated.' }
            format.json { render :show, status: :ok, location: @clinic }
          else
            format.html { render :edit }
            format.json { render json: @clinic.errors, status: :unprocessable_entity }
          end
        end
      end



  def destroy
    @clinic.destroy
    respond_to do |format|
      format.html { redirect_to clinics_url, notice: 'Clinic was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_clinic
      @clinic = Clinic.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user)
      .permit(:first_name, :last_name, :email, :password, :password_confirmation, :phone, 
        :practitioner_image,  
        :clinic_logo,
        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

new. html .erb

<div id="ClinicGenerel" class="TabBlock">
  <div class="content">
    <div class="content clinic">
      <h2 class="page-title">Generel information</h2>
      <%= simple_form_for [@clinic] do |f| %>
        <%= render 'clinics_fields', :f => f %>
        <div class="submit-container">
          <%= f.submit "Gem", :class => 'btn blue'  %>
        </div>
      <% end %>
    </div>
  </div>
</div>

Log

Started POST "/clinics" for ::1 at 2020-03-09 20:35:16 +0100
Processing by ClinicsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"lkftNxR96kkoI4+m00fSevQC+dZU9KsqhvWrcWg+7RPNWd593lPj2aWBdM2vfX83k4t2WUb2LODPFJVnFwJkZg==", "clinic"=>{"clinic_name"=>"Testin", "clinic_address"=>"add", "clinic_zip_code"=>"34334", "clinic_city"=>"adsd", "clinic_municipality"=>"sadsa", "clinic_about"=>"dasds", "clinic_mail"=>"kvnana@yaoo.dk", "clinic_phone"=>"24210566", "clinic_website"=>""}, "commit"=>"Gem"}
  User Load (0.8ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 96 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ app/controllers/clinics_controller.rb:25
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.8ms)



ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):

app/controllers/clinics_controller.rb:25:in `create'

Ответы [ 3 ]

0 голосов
/ 09 марта 2020

Из кодовой базы, которой вы поделились, кажется, вы запутались, как создавать вложенные отношения в одном запросе. т. е. создать пользователя и clini c в одном запросе, скажем, в вашем случае выше.

Есть несколько решений, чтобы просто заставить его работать.

  1. См. правильные параметры

Parameters: {"utf8"=>"✓", "authenticity_token"=>"1MpJgYCodgCLbJI2i5pZEjAV/a0qvJRHuLaSaim9Y3byHDAAqa4IbogbJNEzPTpyDNMRM3Wz5UFRU00CcBOYBQ==", "clinic"=>{"clinics"=>{"clinic_name"=>"My clinic", "clinic_address"=>"sdd", "clinic_zip_code"=>"343443", "clinic_city"=>"sadsasa", "clinic_municipality"=>"dsd", "clinic_about"=>"sasd", "clinic_mail"=>"kvnirva@yaho.dk", "clinic_phone"=>"24210866", "clinic_website"=>""}}, "commit"=>"Gem"}

Если вы посмотрите свой журнал, вы не найдете ни одного ключа clinics_attributes, но вы пытаетесь получить с помощью params[:clinics_attributes] в действии create, которое будет return nil

Быстрое исправление: замените params[:clinics_attributes] на params[:clinic][:clinics] в вас create action

Лучшая версия - это то, что предлагает @ sahil-grover в ответе выше.

Но вам все равно нужно понимать структуру параметров и настраивать способ доступа к ним.

С помощью это изменение вам нужно заменить params[:clinics_attributes] на params[:clinic] в вас create action

Немного лучшая версия решения 2 - использовать сильные параметры (user_params в вашем случае)
0 голосов
/ 09 марта 2020

Я думаю, что все заработало, изменив
@clinic = current_user.clinics.new(params[:clinic]) на
@clinic = current_user.clinics.new(clinic_params)

и вместо def user_params я добавил это

def clinic_params
  params.require(:clinic).permit(:id, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city)
end
0 голосов
/ 09 марта 2020

Измените new. html .erb на

<div id="ClinicGenerel" class="TabBlock">
  <div class="content">
    <div class="content clinic">
      <h2 class="page-title">Generel information</h2>
      <%= simple_form_for [@clinic] do |f| %>
        <%= render 'clinics_fields', :f => f %>
        <div class="submit-container">
          <%= f.submit "Gem", :class => 'btn blue'  %>
        </div>
      <% end %>
    </div>
  </div>
</div>

и попробуйте снова. <%= f.simple_fields_for(:clinics) do |p| %> необходимо удалить, поскольку <%= f.simple_fields_for(:clinics) do |p| %> попытается l oop сверх clinics association из clinic, которого не существует.

...