繁体   English   中英

从 has_many 更改为 has_one 关系 rails

[英]Changing from has_many to has_one relation rails

这里personaldetails 属于_to user,而给出的关系是has_many,这是错误的。我想将has_many 关系转换为has_one 关系,即User has_one personaldetails。 当我直接更改关系时,出现错误“未初始化的常量 User::Personaldetails。请指导我如何转换关系。

个人资料.rb

class Personaldetail < ApplicationRecord
    belongs_to :user
end

用户.rb

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

路线.rb

 resources :users, except: [:new] do
  resources :personaldetails
 end

user_steps_controller.rb

class UserStepsController < ApplicationController
    include Wicked::Wizard
    steps : :personaldetails
    def show
        @user = current_user
        @personaldetails = @user.personaldetails.build
        render_wizard
    end

def update
    @user = current_user
    @user.update!(user_params)
    render_wizard @user
end
   
private

def user_params
    params.require(:user).permit(:name, :password, :password_confirmation, :user_id,
      personaldetails_attributes: [:id,:first_name, :last_name, :gmail, :mobile_no, :city, :state, :pin_code, :_destroy])
end
end

个人详情.html.erb

<%= form_with(model: @user, url: wizard_path, local: true) do |form| %> 
  <%= form.fields_for :personaldetail,Personaldetail.new do |info| %>
    <%= render 'personaldetails_field', form: info %>
  <% end %>
  <%= form.submit %>
<% end %>

_personaldetails_field.html.erb

<div class="field">
<%= form.label :First_name %><br />
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :Last_name %><br />
<%= form.text_field :last_name %>
</div>
<div class="field">
<%= form.label :email %><br />
<%= form.text_field :gmail %>
</div>
<div class="field">
<%= form.label :Mobile_number %><br />
<%= form.text_field :mobile_no %>
</div>
<div class="field">
<%= form.label :City %><br />
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :State %><br />
<%= form.text_field :state %>
</div>
<div class="field">
<%= form.label :Pincode %><br />
<%= form.text_field :pin_code %>
</div>

所以解决方案是:

个人资料.rb

class Personaldetail < ApplicationRecord
    belongs_to :user
end

用户.rb

class User < ApplicationRecord
 has_one :personaldetails, dependent: :destroy
accepts_nested_attributes_for :personaldetails, reject_if: :all_blank, allow_destroy: true
end

路线.rb

 resources :users, except: [:new] do
  resources :personaldetail
 end

user_steps_controller.rb

class UserStepsController < ApplicationController
    include Wicked::Wizard
    steps : :personaldetails
    def show
        @user = current_user
        render_wizard
    end

def update
    @user = current_user
    @user.update!(user_params)
    render_wizard @user
end
   
private

def user_params
    params.require(:user).permit(:name, :password, :password_confirmation, :user_id,
      personaldetails_attributes: [:id,:first_name, :last_name, :gmail, :mobile_no, :city, :state, :pin_code, :_destroy])
end
end

个人详细信息.html.erb

<%= form_with(model: @user, url: wizard_path, local: true) do |form| %> 
  <%= form.fields_for :personaldetail,@user.personaldetail || @user.build_personaldetail do |info| %>
    <%= render 'personaldetail_field', form: info %>
  <% end %>
  <%= form.submit %>
<% end %>

_personaldetail_field.html.erb

<div class="field">
<%= form.label :First_name %><br />
<%= form.text_field :first_name %>
</div>
<div class="field">
<%= form.label :Last_name %><br />
<%= form.text_field :last_name %>
</div>
<div class="field">
<%= form.label :email %><br />
<%= form.text_field :gmail %>
</div>
<div class="field">
<%= form.label :Mobile_number %><br />
<%= form.text_field :mobile_no %>
</div>
<div class="field">
<%= form.label :City %><br />
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :State %><br />
<%= form.text_field :state %>
</div>
<div class="field">
<%= form.label :Pincode %><br />
<%= form.text_field :pin_code %>
</div>

尝试使用: has_one:personaldetail, dependent: :destroy Rails 正在从名称和关联类型中猜测 class 名称,因此使用 has_many 他们将尝试单数化关联名称(personaldetails => Personaldetail)但使用 has_one 他们将尝试按原样到达它(个人详情 => 个人详情)

正如 spickermann 的评论一样, has_many关系需要复数形式,而has_one需要单数形式。 也就是说,您应该已经能够从以下方面推断出关系:

@user.personaldetails # user has many personal details
@user.personaldetail  # user has one personal detail

只是一个考虑:当对象/模型没有正确命名时,会出现许多奇怪的情况。 根据经验,您应该为需要命名的 object 使用最合适和最精确的英文名词。 在这种情况下,这将对您有很大帮助。 在正常的英语中,说“用户有个人详细信息”有点奇怪,但你当然会说“有个人详细信息”。 特别是涉及到 ActiveRecord 关联时,Rails 语法应该尽可能接近英语,以避免以后的误解。 例如,如果 model 被称为“帐户”或“个人资料”而不是“PersonalDetail”,我想这种混淆不会出现。

一些建议/评论

  1. 保持 model 名称为 CamelCase,如PersonalDetail而不是Personaldetail和关联名称has_one:personal_detail
  2. 使用has_one关系,您可以使用 user.build_personal_detail.save 创建user.build_personal_detail.save
  3. 当您再次运行第二步时,它将在personal_details表中创建另一条记录,并在该事务中返回新记录。 但是,之后当您尝试查询时,它将返回第一个创建的personal_details 记录而不是新记录。 这是因为ActiveRecord默认按 id 排序,并且has_one关系的限制为 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM