Here personaldetails belongs_to user and the relation given is has_many which is wrong.I want to convert the has_many relation to has_one relation ie User has_one personaldetails. When I change the relation directly I am getting an error "uninitialized constant User::Personaldetails. Please guide me how to convert the relation.
Personaldetail.rb
class Personaldetail < ApplicationRecord
belongs_to :user
end
User.rb
class User < ApplicationRecord
has_many :personaldetails, dependent: :destroy
accepts_nested_attributes_for :personaldetails, reject_if: :all_blank, allow_destroy: true
end
routes.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
personaldetails.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>
So the solution is:
Personaldetail.rb
class Personaldetail < ApplicationRecord
belongs_to :user
end
User.rb
class User < ApplicationRecord
has_one :personaldetails, dependent: :destroy
accepts_nested_attributes_for :personaldetails, reject_if: :all_blank, allow_destroy: true
end
routes.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
personaldetail.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>
try with: has_one:personaldetail, dependent: :destroy
Rails are guessing class name from name AND type of association, so with has_many they will try to singularize association name (personaldetails => Personaldetail) but with has_one they will try to reach it as is (personaldetails => Personaldetails)
As in the comment by spickermann, has_many
relationship wants plural form and has_one
the singular form. That is to say, you should already be able to infer the relationship from:
@user.personaldetails # user has many personal details
@user.personaldetail # user has one personal detail
Just a consideration: many weird cases arise when objects/models are not properly named. As a rule of thumb, you should use the most fitting and precise English noun for the object you need to name. That will help you hugely in cases like this. In normal English language, it is somehow strange to say "a user has a personal detail" but you would say of course "has personal details". Particularly when it comes to ActiveRecord associations, Rails syntax should be the nearest as possible to English language, to avoid later misunderstandings. I guess this confusion would not have arisen if instead of "PersonalDetail", the model was called "Account" or "Profile", for instance.
Few suggestions/comments
PersonalDetail
rather than Personaldetail
and association name has_one:personal_detail
has_one
relation you can create the object using user.build_personal_detail.save
personal_details
table and in that transaction it will return the new record. But, after that when you try to query it will return the 1st created personal_details record rather than new one. That's because ActiveRecord
by default sorts by id and limit 1 for has_one
relation
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.