首先或创建方法,创建重复项

时间:2017-04-30 15:23:22

标签: ruby-on-rails ruby

您好我正在尝试使用find或create方法更新技能(如果已存在)或创建它(如果不存在)。我可以创建一个新技能,但是当我尝试更新已经存在的技能时,它会更新技能,但也会创建具有相同数据的重复技能。

def create
  @project = Project.find params[:project_id]
  @skills_required = @project.skills_requireds.new(skills_required_params)
  skills = SkillsRequired.where(skills_required_params.slice(:skill_id)).first_or_create
  skills.update(skills_required_params)
  respond_to do |format|
    if @skills_required.save    
      format.html{ redirect_to @project, notice: "Skills required added for #{@project.projectName}" }
    else
      format.html{ redirect_to @project, notice: "Something went wrong, unable to update required skills " }
    end
  end
end

形式:

<div class="section">
  <div class="top-border left"></div>
  <div class="top-border right"></div>
  <h3> Skill Required</h3>
  <%= form_for([@project, SkillsRequired.new]) do |f| %>
    <div class="field">
      <%= f.label :skill_id %><br>
      <%= f.collection_select :skill_id, Skill.all, :id, :skillType, :prompt => "Select Skill" %>
    </div>
    <div class="field">
      <%= f.label :numWorkers %><br>
      <%= f.number_field :numWorkers %>
    </div>
    <div class="field">
      <%= f.label :skillLevel %><br>
      <%= f.text_field :skillLevel %>
    </div>
    <%=f.submit "Add Skill" %>
  <%end%>
</div>

我已经尝试将一个skill_required destroy添加到我的控制器中,但这不允许我添加新技能。任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

你正在接近这个问题。您需要进行模型级验证,以强制skill requirements有效:

# Your model names should be nouns - not adjectives
class SkillRequirement < ApplicationRecord
  validates_uniqueness_of :skill_id, scope: :project_id'
end

如果您希望用户能够指定相同技能但在不同级别,您可以这样做:

# Your model names should be nouns - not adjectives
class SkillRequirement < ApplicationRecord
  validates_uniqueness_of :skill_id, scope: [:project_id, :level] 
end

您还应该将其与数据库索引结合使用以避免竞争条件。

add_index(:skill_requirements, [:project_id, :skill_id], unique: true, name: 'by_skill_and_project')

由于更新现有的技能要求应该通过单独的更新操作来处理,因此您不需要控制器中的所有臃肿:

class SkillRequirementsController
  before_action :set_project

  def create
    @skill_requirement = @project.skill_requirements.new(skill_requirement_params)
    if @skill_requirement.save
      redirect_to @project
    else
      render :new
    end
  end

  def update
    @skill_requirement = @project.skill_requirements.find(params[:id])
    if @skill_requirement.update(skill_requirement_params)
      redirect_to @project
    else
      render :edit
    end
  end

  private 

  def set_project
    @project = Project.find(params[:project_id])
  end

  def skill_requirement_params
    params.require(:skill_requirement).permit(:)
  end
end