Rails: параметр отсутствует или значение пусто: admin - PullRequest
1 голос
/ 18 июня 2020

Я работаю над проектом Rails и использую пространство имен для моделей и контроллеров. То есть дочерние модели помещаются в каталог с именем user, а контроллеры помещаются в каталог с именем users.

Для большей ясности у меня есть модель user с дочерним admin и модели student, использующие Single Table Inheritance (STI) . Эти дочерние модели наследуют все атрибуты родительской модели и могут индивидуально определять свои проверки и методы и помещаются в каталог с именем user.

Я также имеют admins_controller и students_controller, которые используют модель admin и модель student соответственно. Эти контроллеры помещаются в каталог с именем users.

Вот мой код ;

Модель пользователя :

class User < ApplicationRecord
  has_secure_password
end

Модель администратора :

class User::Admin < User
end

Модель ученика :

class User::Student < User
end

Контроллер администратора :

class Users::AdminsController < ApplicationController
  before_action :set_admin, only: [:show, :edit, :update, :destroy]

  # GET /admins
  # GET /admins.json
  def index
    @admins = User::Admin.all
  end

  # GET /admins/1
  # GET /admins/1.json
  def show
  end

  # GET /admins/new
  def new
    @admin = User::Admin.new
  end

  # GET /admins/1/edit
  def edit
  end

  # POST /admins
  # POST /admins.json
  def create
    @admin = User::Admin.new(admin_params)

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

  # PATCH/PUT /admins/1
  # PATCH/PUT /admins/1.json
  def update
    respond_to do |format|
      if @admin.update(admin_params)
        format.html { redirect_to users_admin_path(@admin), notice: 'Admin was successfully updated.' }
        format.json { render :show, status: :ok, location: users_admin_path(@admin) }
      else
        format.html { render :edit }
        format.json { render json: @admin.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /admins/1
  # DELETE /admins/1.json
  def destroy
    @admin.destroy
    respond_to do |format|
      format.html { redirect_to users_admins_url, notice: 'Admin was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_admin
      @admin = User::Admin.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def admin_params
      params.require(:admin).permit(:email, :password, :role)
  end
end

Маршруты :

Rails.application.routes.draw do
  namespace :users do
    resources :admins
    resources :students
  end
end

index. html .erb :

<p id="notice"><%= notice %></p>

<h1>Admins</h1>

<table>
  <thead>
    <tr>
      <th>Email</th>
      <th>Password</th>
      <th>Role</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @admins.each do |admin| %>
      <tr>
        <td><%= admin.email %></td>
        <td><%= admin.password %></td>
        <td><%= admin.role %></td>
        <td><%= link_to 'Show', users_admin_path(admin) %></td>
        <td><%= link_to 'Edit', edit_users_admin_path(admin) %></td>
        <td><%= link_to 'Destroy', users_admin_path(admin), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Admin', new_users_admin_path %>

показать . html .erb :

<p id="notice"><%= notice %></p>

<p>
  <strong>Email:</strong>
  <%= @admin.email %>
</p>

<p>
  <strong>Password:</strong>
  <%= @admin.password %>
</p>

<p>
  <strong>Role:</strong>
  <%= @admin.role %>
</p>

<%= link_to 'Edit', edit_users_admin_path(@admin) %> |
<%= link_to 'Back', users_admins_path %>

_form. html .erb :

<% if @admin.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@admin.errors.count, "error") %> prohibited this admin from being saved:</h2>

    <ul>
      <% @admin.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

<div class="field">
  <%= form.label :email %>
  <%= form.text_field :email %>
</div>

<div class="field">
  <%= form.label :password %>
  <%= form.text_field :password %>
</div>

<div class="field">
  <%= form.label :role %>
  <%= form.text_field :role %>
</div>

<div class="actions">
  <%= form.submit %>
</div>

новый. html .erb :

<h1>New Admin</h1>

<%= form_with(model: @admin, url: users_admins_path, local: true) do |form| %>
  <%= render partial: 'form', admin: @admin, locals: { form: form } %>
<% end %>

<%= link_to 'Back', users_admins_path %>

изменить. html .erb :

<h1>Editing Admin</h1>

<%= form_with(model: @admin, url: users_admin_path(@admin), local: true) do |form| %>
  <%= render partial: 'form', admin: @admin, locals: { form: form } %>
<% end %>

<%= link_to 'Show', users_admin_path %> |
<%= link_to 'Back', users_admins_path %>

Однако, когда я пытаюсь создать нового администратора или обновить уже существующий администратор, я получаю сообщение об ошибке:

параметр отсутствует или значение пусто: admin

Я попытался устранить причину проблемы, но нет удачи пока. Мы будем очень признательны за любую помощь.

1 Ответ

1 голос
/ 18 июня 2020

Я наконец понял это после тщательного изучения моих журналов.

Вот как я решил это :

Я проверил параметры запроса действия create, и я понял, что это был такой формат:

{"authenticity_token"=>"qJWlHz7Z5myTH3dwNIjjSOzRDY7JN+LoovaG+8dMBnGFRWImJKlWp8cgF7kwTqJXIxqU2fGVkqW9nhOAJ8vFIg==",
 "user_admin"=>{"email"=>"promise@gmail.com", "password"=>"[FILTERED]", "role"=>""},
 "commit"=>"Create Admin"}

application trace screenshot

Значит, параметры запроса имеют ha sh ключ user_admin со значениями email, password и role, тогда как я передавал ключ admin ha sh в моем admins_controller.

Все, что мне нужно было сделать, это чтобы изменить частный метод admins_params в моем admins_controller:

Из этого :

def admin_params
  params.require(:admin).permit(:email, :password, :role)
end

На это :

def admin_params
  params.require(:user_admin).permit(:email, :password, :role)
end

и это решило проблему.

Если у вас есть такая проблема, всегда старайтесь проверять параметры запроса в ваших журналах или трассировке вашего приложения. Это даст вам много информации, которая поможет вам решить проблему.

Вот и все.

Надеюсь, это поможет

...