This has been bugging me for days, I need some help.
I have a model Project
with a has many relationship with the user (user has many projects). The projects are already predefined, and has a validates_uniqueness_of :roles, scope: :user_id, message: 'already exists'
constraint defined in the model.
I currently have a form with checkboxes like so:
<h1>Create New Project</h1>
<%= form_for(@project) do |f| %>
<%= f.label :user %>
<%= f.select :user_id, @users %>
<%= f.label :projects %>
<ul>
<% @user_projects.each do |project| %>
<li>
<%= f.check_box("projects",
{ multiple: true },
"#{project}", nil)
%>
<%= "#{project}" %>
</li>
<% end %>
</ul>
<%= f.submit 'Create Projects' %>
<% end %>
<% if @project.errors.any? %>
<ul id='form-error-list'>
<% @project.errors.full_messages.each do |message| %>
<li class='error-message'>
<%= message %>
</li>
<% end %>
</ul>
<% end %>
Where @users = User.all.collect { |user| [user.email, user.id] }
and @user_projects = ['project 1', 'project 2', #...]
I'd like to save multiple projects for each users, and that by itself works fine. The only issue I have is that when I try to save a project that already exists in the database along with a project that doesn't, the page does not get rendered with an error message.
For example assume that user_id: 1, project: "project 1"
exists in the database. If in the form, I check projects 1 and 2 with the same user id and try to save it, the instance with project 1 will not saved, but project 2 will. I'd like to make it so that if one or more validation failed, then the new page will be rendered with an error.
Here are my controller actions for Projects:
projects controller:
def new
@project = Project.new
@users = User.all.collect { |user| [user.email, user.id] }
@user_projects = ['project 1', 'project 2', #...]
end
def create
@project = Project.new(project_params)
@users = User.all.collect
@user_projects = ['project 1', 'project 2', #...]
if User.find_by(id: project_params['user_id']).projects.build(
project_params['names'].map { |name| { names: name } }
).each(&:save)
redirect_to projects_path, notice: 'Projects saved successfully'
else
render :new
end
end
private
def project_params
params.require(:project).permit(:user_id, names : [])
end
The only way I got it to work was implementing this into my create action:
build_multiple_projects = User.find_by(id: project_params['user_id']).projects.build(
project_params['names'].map { |name| { names: name } }
)
@errors = build_multiple_projects.map { |project|
if Project.find_by({
user_id: project.user_id,
names: project.names
}).present?
project.save
project.errors.full_messages.each { |message| message }
else
nil
end
}.uniq.compact
if @errors.present?
render :new
else
build_multiple_projects.each(&:save)
redirect_to projects_path, notice: 'User projects have successfully been created'
end
But honestly I smell bad code in this, and don't want to use it.
Please provide me with tips! Thank you!
Aucun commentaire:
Enregistrer un commentaire