当尝试在rails中添加具有重复索引的条目时,请避免出现异常



我有三种型号:

  • 用户
  • 难题
  • 解决方案

解决方案代表用户首次解决给定难题。我只想记录第一次的时间-以后的尝试不算在内。该解决方案有一个关于用户谜题组合的索引。

我的迁移看起来是这样的:

class CreateSolutions < ActiveRecord::Migration[6.0]
def change
create_table :solutions do |t|
t.integer :time
t.integer :attempts
t.references :user
t.references :puzzle
t.timestamps
end
add_index :solutions, [:user_id, :puzzle_id], unique: true
end
end

我使用的是MySQL。Puzzle和User模型都有:has_many :solutions

solutions_controller.rb中,我有:

def create
@solution = Solution.new(solution_params)
@solution.user = current_user
@solution.puzzle = Puzzle.find(params["puzzle"])
respond_to do |format|
if @solution.save
format.json { render :show, status: :created }
else
format.json { render json: @solution.errors, status: :unprocessable_entity }
end
end
end

问题是,当我第二次尝试保存谜题时,我得到了一个例外:

ActiveRecord::RecordNotUnique in SolutionsController#create
Mysql2::Error: Duplicate entry '28-13' for key 'index_solutions_on_user_id_and_puzzle_id'

目标:我希望它只是默默地忽略后续保存,而不是抛出异常。

以下是我尝试过的所有解决方案_controller.rb:

  • if @solution.save(validate: false)...
  • if @solution.save(:validate => false)...
  • if @solution.save(false)...

理想情况下,我只想跳过重复索引的验证-我想捕捉其他错误。

在解决方案模型中,您可以添加

validates_uniqueness_of :user_id, scope: :puzzle_id

每次您尝试保存解决方案记录时,它都会运行一个选择查询。如果所选查询解决方案存在记录,则保存将出错。

或者您可以使用first_Or_initialize

Solution.where(user_id: current_user.id, puzzle_id: params[:puzzle][:id]).first_or_initialize(solution_params)

这将检查给定查询的记录是否存在。如果不存在,它将在where条件和solution_params中分配属性。

更新

def create
@solution = Solution.where(user_id: current_user.id, puzzle_id: params[:puzzle][:id]).first_or_initialize(solution_params)
respond_to do |format|
if @solution.save
format.json { render :show, status: :created }
else
format.json { render json: @solution.errors, status: :unprocessable_entity }
end
end
end

如果你这样做,就不需要检查错误消息,如果表中已经存在记录,它将被分配给@solution,而solution params中的数据将不会被分配。如果记录不存在,@solution将被分配where condition和solution_params中的数据(user_id和puzzle_id值将取自where condition中给定的值,其他值来自solution_params(。如果在where condition和solution_params中给出属性数据,则将取solution_params值。

最新更新