所以问题是,当我创建用户配置文件时,它会正确获取用户输入并将其显示在视图上,但是当我编辑它时,它会转到编辑页面,单击提交后会出现错误
配置文件中的类型错误#show 显示 /home/nouman/GitConnect/app/views/profiles/show.html.erb 其中第 22 行提出:
没有将字符串隐式转换为整数提取源(大约 第 22 行):<% @profile.education.each do |edu| %>
<% if edu["degree"].present? %> 学位: <%= edu["degree"] %> <% else %> 学位: 未提供
我正在使用部分新的
这是 _form.html.erb
<%= form_with(model: @profile, local: true) do |form| %>
<% if @profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@profile.errors.count, "error") %> prohibited this profile from being saved:</h2>
<ul>
<% @profile.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :profile_pic %>
<%= form.file_field :profile_pic %>
</div>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, required: true %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.email_field :email, optional: true %>
</div>
<div class="field">
<%= form.label :contact_info %>
<%= form.text_field :contact_info %>
</div>
<div class="field">
<%= form.label :headline %>
<%= form.text_field :headline %>
</div>
<div class="field">
<%= form.label :city %>
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :social_media_links %>
<%= form.text_field :social_media_links, placeholder: 'Link 1', value: @profile.social_media_links[0] %>
<%= form.text_field :social_media_links, placeholder: 'Link 2', value: @profile.social_media_links[1] %>
<%= form.text_field :social_media_links, placeholder: 'Link 3', value: @profile.social_media_links[2] %>
</div>
<div class="field">
<%= form.label :education, "Education" %>
<div class="education-entry">
<%= form.label :degree, "Degree" %>
<%= form.text_field :education, name: "profile[education][][degree]", placeholder: "Enter degree" %>
<%= form.label :institution, "Institution" %>
<%= form.text_field :education, name: "profile[education][][institution]", placeholder: "Enter institution" %>
<%= form.label :graduation_date, "Graduation Date" %>
<%= form.date_select :graduation_date, name: "profile[education][][graduation_date]" %>
</div>
<div class="education-entry">
<%= form.label :degree, "Degree" %>
<%= form.text_field :education, name: "profile[education][][degree]", placeholder: "Enter degree" %>
<%= form.label :institution, "Institution" %>
<%= form.text_field :education, name: "profile[education][][institution]", placeholder: "Enter institution" %>
<%= form.label :graduation_date, "Graduation Date" %>
<%= form.date_select :graduation_date, name: "profile[education][][graduation_date]" %>
</div>
</div>
<div class="field">
<%= form.label :work_experience, "Work Experience" %>
<div class="work-entry">
<%= form.label :position, "Position" %>
<%= form.text_field :work_experience, name: "profile[work_experience][][position]", placeholder: "Enter position" %>
<%= form.label :company, "Company" %>
<%= form.text_field :work_experience, name: "profile[work_experience][][company]", placeholder: "Enter company" %>
<%= form.label :start_date, "Starting Date" %>
<%= form.date_select :start_date, name: "profile[work_experience][][start_date]", placeholder: "Enter Starting date" %>
<%= form.label :end_date, "Ending Date" %>
<%= form.date_select :end_date, name: "profile[work_experience][][end_date]", placeholder: "Enter Ending date" %>
</div>
<div class="work-entry">
<%= form.label :position, "Position" %>
<%= form.text_field :work_experience, name: "profile[work_experience][][position]", placeholder: "Enter position" %>
<%= form.label :company, "Company" %>
<%= form.text_field :work_experience, name: "profile[work_experience][][company]", placeholder: "Enter company" %>
<%= form.label :start_date, "Starting Date" %>
<%= form.date_select :start_date, name: "profile[work_experience][][start_date]", placeholder: "Enter Starting date" %>
<%= form.label :end_date, "Ending Date" %>
<%= form.date_select :end_date, name: "profile[work_experience][][end_date]", placeholder: "Enter Ending date" %>
</div>
</div>
<div class="actions">
<%= form.submit %>
</div>
<%
end %>
编辑.html.erb
<h1>Edit Your Profile</h1>
<%= form_with(model: @profile, local: true) do |form| %>
<% if @profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@profile.errors.count, "error") %> prohibited this profile from being saved:</h2>
<ul>
<% @profile.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, required: true %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.email_field :email, optional: true %>
</div>
<div class="field">
<%= form.label :contact_info %>
<%= form.text_field :contact_info %>
</div>
<div class="field">
<%= form.label :profile_pic %>
<%= form.file_field :profile_pic %>
</div>
<div class="field">
<%= form.label :headline %>
<%= form.text_field :headline %>
</div>
<div class="field">
<%= form.label :city %>
<%= form.text_field :city %>
</div>
<div class="field">
<%= form.label :social_media_links %>
<%= form.text_field :social_media_links, placeholder: 'Link 1', name: "profile[social_media_links][]", value: @profile.social_media_links[0] %>
<%= form.text_field :social_media_links, placeholder: 'Link 2', name: "profile[social_media_links][]", value: @profile.social_media_links[1] %>
<%= form.text_field :social_media_links, placeholder: 'Link 3', name: "profile[social_media_links][]", value: @profile.social_media_links[2] %>
</div>
<div class="field">
<%= form.label :education, "Education" %>
<% @profile.education.each_with_index do |edu, index| %>
<div class="education-entry">
<%= form.label "education[#{index}][degree]", "Degree" %>
<%= form.text_field "education[#{index}][degree]", value: edu["degree"], placeholder: "Enter degree" %>
<%= form.label "education[#{index}][institution]", "Institution" %>
<%= form.text_field "education[#{index}][institution]", value: edu["institution"], placeholder: "Enter institution" %>
<%= form.label "education[#{index}][graduation_date]", "Graduation Date" %>
<%= form.date_select "education[#{index}][graduation_date]", selected: edu["graduation_date"] %>
</div>
<% end %>
</div>
<div class="field">
<%= form.label :work_experience, "Work Experience" %>
<% @profile.work_experience.each_with_index do |exp, index| %>
<div class="work-entry">
<%= form.label "work_experience[#{index}][position]", "Position" %>
<%= form.text_field "work_experience[#{index}][position]", value: exp["position"], placeholder: "e.g. Developer" %>
<%= form.label "work_experience[#{index}][company]", "Company" %>
<%= form.text_field "work_experience[#{index}][company]", value: exp["company"], placeholder: "e.g. Company A" %>
<%= form.label "work_experience[#{index}][duration]", "Duration" %>
<%= form.text_field "work_experience[#{index}][duration]", value: exp["duration"], placeholder: "e.g. 2020-2022" %>
</div>
<% end %>
</div>
<div class="actions">
<%= form.submit "Update Profile" %>
</div>
<% end %>
show.html.erb
<h1>Hello <%[email protected]%></h1>
<p><strong>Email:</strong> <%= current_user.email || 'Not provided' %></p>
<p><strong>Contact Info:</strong> <%= @profile.contact_info || 'Not provided' %></p>
<p><strong>City:</strong> <%= @profile.city || 'Not provided' %></p>
<p><strong>Headline:</strong> <%= @profile.headline || 'Not provided' %></p>
<p><strong>Profile Picture:</strong></p>
<% if @profile.profile_pic.present? %>
<%= image_tag @profile.profile_pic.url %>
<% else %>
<p>No profile picture uploaded.</p>
<% end %>
<h2>Social Media Links</h2>
<ul>
<% @profile.social_media_links.each do |link| %>
<li><%= link.present? ? link : 'Not provided' %></li>
<% end %>
</ul>
<h2>Education</h2>
<ul>
<% @profile.education.each do |edu| %>
<li>
<% if edu["degree"].present? %>
<strong>Degree:</strong> <%= edu["degree"] %>
<% else %>
<strong>Degree:</strong> Not provided
<% end %>
<% if edu["institution"].present? %>
<strong>Institution:</strong> <%= edu["institution"] %>
<% else %>
<strong>Institution:</strong> Not provided
<% end %>
<% if edu["graduation_date"].present? %>
<strong>Graduation Date:</strong> <%= edu["graduation_date"] %>
<% else %>
<strong>Graduation Date:</strong> Not provided
<% end %>
</li>
<% end %>
</ul>
<h2>Work Experience</h2>
<ul>
<% @profile.work_experience.each do |exp| %>
<li>
<% if exp["position"].present? %>
<strong>Position:</strong> <%= exp["position"] %>
<% else %>
<strong>Position:</strong> Not provided
<% end %>
<% if exp["company"].present? %>
<strong>Company:</strong> <%= exp["company"] %>
<% else %>
<strong>Company:</strong> Not provided
<% end %>
<% if exp["start_date"].present? %>
<strong>Start Date:</strong> <%= exp["start_date"] %>
<% else %>
<strong>Start Date:</strong> Not provided
<% end %>
<% if exp["end_date"].present? %>
<strong>End Date:</strong> <%= exp["end_date"] %>
<% else %>
<strong>End Date:</strong> Not provided
<% end %>
</li>
<% end %>
</ul>
<%= link_to 'Edit Profile', edit_profile_path(@profile) %>
profile_controller.html.erb
class ProfilesController < ApplicationController
before_action :authenticate_user!, except: [:index]
before_action :set_profile, only: %i[edit update destroy]
def show
@profile = current_user.profile
return unless @profile.nil?
redirect_to new_profile_path, alert: 'Please create your profile Frist'
end
def new
@profile = Profile.new
end
def create
@profile = current_user.build_profile(profile_params)
if @profile.save
redirect_to @profile, notice: 'Profile was successfully created.'
else
render :new, status: :unprocessable_entity
end
end
def edit; end
def update
if @profile.update(profile_params)
redirect_to @profile, notice: 'Profile was successfully updated.'
else
render :edit, status: :unprocessable_entity
end
end
private
def profile_params
params.require(:profile).permit(:name, :email, :contact_info, :profile_pic, :headline, :city,
social_media_links: %i[link1 link2 link3], education: %i[degree institution graduation_date], work_experience: %i[company position start_date end_date])
end
def set_profile
@profile = current_user.profile
redirect_to new_profile_path, alert: 'Profile not found. Please create a profile.' unless @profile
end
end
架构.rb
create_table "profiles", force: :cascade do |t|
t.string "name", null: false
t.string "email", null: false
t.string "profile_pic"
t.string "contact_info"
t.string "headline"
t.string "city"
t.integer "years_of_experience"
t.json "skill_sets", default: []
t.json "social_media_links", default: []
t.json "education", default: []
t.json "work_experience", default: []
t.bigint "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_profiles_on_user_id"
end
创建数据库后有一个东西,它显示为
[#<Profile:0x00007f2fb965f1e0
id: 18,
name: "Nouman",
email: "[email protected]",
profile_pic: nil,
contact_info: "030700",
headline: "This is a developer profile",
city: "lahore",
years_of_experience: nil,
skill_sets: [],
social_media_links: [],
education: [{"degree"=>"BSSE", "institution"=>"Punjab College"}, {"degree"=>"Intermediate", "institution"=>"Punjab College"}],
work_experience: [{"company"=>"IIFA Tech", "position"=>"Intern"}, {"company"=>"Recurso Labs", "position"=>"Intern"}],
user_id: 15,
created_at: Fri, 04 Oct 2024 08:21:48.885126000 UTC +00:00,
updated_at: Fri, 04 Oct 2024 08:21:48.885126000 UTC +00:00>]
但是当我编辑它时,它会将其更改为
[#<Profile:0x00007f2fb96fe920
id: 18,
name: "Nouman",
email: "[email protected]",
profile_pic: nil,
contact_info: "030700",
headline: "This is a developer profile",
city: "lahore",
years_of_experience: nil,
skill_sets: [],
social_media_links: [],
education:
{"0"=>{"degree"=>"BSCS", "institution"=>"COMSATS"}, "1"=>{"degree"=>"Intermediate", "institution"=>"Punjab College"}},
work_experience: {"0"=>{"company"=>"IIFA ", "position"=>"Developers"}, "1"=>{"company"=>"Recurso Labs", "position"=>"Intern"}},
user_id: 15,
created_at: Fri, 04 Oct 2024 08:21:48.885126000 UTC +00:00,
updated_at: Fri, 04 Oct 2024 08:23:16.639720000 UTC +00:00>]
这不是构建应用程序的可行方法。我不会试图挽救这种陷入困境的尝试,至少会尝试将您推向正确的方向。
数组类型列对于非常有限的一组特殊情况来说是一个有用的工具,但不应该是在关系数据库中构建数据的方式。尤其是如果您使用数组列来存储哈希值,则更是如此。
相反,每一行应该包含一组值,并且您应该使用单独的表来存储相关实体。这就是所谓的第一范式,是良好数据库设计的核心租户。
例如,您应该为教育创建一个单独的表:
class Profile < ApplicationRecord
has_many :educations
end
# rails g model education profile:references degree:string institute:string graduation_date:date
class Education < ApplicationRecord
belongs_to :profile
end
这使用一对多关联,但如果您想避免重复,关联也可以是多对多。
这可以让您真正标准化该表的属性,而不是弄得一团糟。它还允许您利用 Rails 提供的功能来创建嵌套模型:
class Profile < ApplicationRecord
has_many :educations
accepts_nested_attributes_for :educations
end
<%= form_with(model: @profile) do |form| %>
# ... other fields
<%= form.fields_for(:educations) do |education_fields| %>
<div class="education">
<div class="field">
<%= education_fields.label :degree %>
<%= education_fields.text_field :degree %>
</div>
<div class="field">
<%= education_fields.label :institute %>
<%= education_fields.text_field :institute %>
</div>
<div class="field">
<%= education_fields.label :graduation_date %>
<%= education_fields.date_field :graduation_date %>
</div>
</div>
<% end %>
# ...
<% end %>
class ProfilesController < ApplicationController
before_action :authenticate_user!, except: [:index]
before_action :set_profile, only: %i[edit update destroy]
# ...
def new
@profile = Profile.new
3.times { @profile.educations.new } # seeds the fields on the form
end
private
def profile_params
# Line breaks are free. Keep your line lengths readible.
params.require(:profile)
.permit(
# ...
education_attributes: %i[degree institution graduation_date],
# ...
)
end
# ...
end
然后您需要对其他关系重复此过程。是的,这确实意味着您必须退后一步并重做您的工作,但它会带来巨大的回报。
参见: