【问题标题】:Rails: One-to-One relationship not workingRails:一对一关系不起作用
【发布时间】:2020-10-16 03:19:34
【问题描述】:

我正在开发一个 Rails 项目,并且我正在为模型和控制器使用命名空间。也就是说,子模型(adminstudent)被放在名为 user 的目录中,而控制器被放在名为 users 的目录中。

我还有admins_controllerstudents_controller 分别使用admin 模型和student 模型。这些控制器使用users 目录命名空间。

然后我有一个personal_info 模型,其中包含有关user 的更多详细信息,例如性别、年龄、出生日期。 personal_info 表与user 模型是一对一的关系。

这是我的代码

个人信息模型

class PersonalInfo < ApplicationRecord
  belongs_to :user
end

用户模型

class User < ApplicationRecord
  has_secure_password
  has_one :personal_info, class_name: 'PersonalInfo', dependent: :destroy
  accepts_nested_attributes_for :personal_info, allow_destroy: true
end

管理模式

class User::Admin < 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
    @admin.build_personal_info
  end

  # GET /admins/1/edit
  def edit
  end

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

    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(:user_admin).permit(
      :email, :password, :role_id, 
      personal_info_attributes: [ :id, :first_name, :last_name, :phone, 
                                   :gender, :dob, :address, :city, :state, 
                                   :country ]
    )
  end
end

路线

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

_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 %>

<%= fields_for :personal_info do |form| %>
  <div class="field">
    <%= form.label :first_name %>
    <%= form.text_field :first_name %>
  </div>

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

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

<%= fields_for :personal_info do |form| %>
  <div class="field">
    <%= form.label :phone %>
    <%= form.text_field :phone %>
  </div>
<% end %>

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

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

new.html.erb

<h1>Editing 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 %>

但是,当我在向显示的表单添加输入后尝试创建新的admin 或更新现有的admin 时,没有Personal Info 数据保存在数据库中。它们都是nil

PersonalInfo Load (0.3ms) SELECT "personal_infos".* FROM "personal_infos" WHERE "personal_infos"."user_id" = $1 LIMIT $2 [["user_id", 6], ["LIMIT", 1]]

=> #

我试图解决这个问题,但还没有运气。任何形式的帮助都将受到高度赞赏。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    您应该在管理表单中调用您的fields_for

    <%= form.fields_for :personal_info do |form| %>
    

    否则,它会独立于管理员发送这些参数,而不是按照您的意愿嵌套。

    fwiw,为了更好地阅读,我会考虑重命名您的内部个人信息表单变量,以免与管理表单变量发生冲突。但这只是一个建议。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2011-08-28
      • 2014-05-11
      • 2020-03-14
      相关资源
      最近更新 更多