首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Rails:同时创建的重复记录

Rails:同时创建的重复记录
EN

Stack Overflow用户
提问于 2017-07-24 21:49:51
回答 2查看 1.4K关注 0票数 1

我的Rails应用程序发生了一些奇怪的事情。每次用户访问我以前创建的唯一url时,都会调用控制器操作并将记录保存到表中。

不幸的是,有时会创建两个相同的记录,而不是只创建一个。我添加了一个"validates_uniqueness_of“,但它不起作用。

我的控制器代码:

代码语言:javascript
复制
class ShorturlController < ApplicationController
  def show
    @shorturl = ShortUrl.find_by_token(params[:id])
    @card = Card.find(@shorturl.card_id)
    @subscriber = BotUser.find_by_sender_id(params['u'])
    @letter_campaign = Letter.find(@card.letter_id).campaign_name.downcase

    if AnalyticClic.where(card_id: @card.id, short_url_id: @shorturl.id, bot_user_id: @subscriber.id).length != 0
      @object = AnalyticClic.where(card_id: @card.id, short_url_id: @shorturl.id, bot_user_id: @subscriber.id)
      @ccount = @object[0].clicks_count
      @object.update(updated_at: Time.now, clicks_count: @ccount += 1)
    else
      AnalyticClic.create(card_id: @card.id, short_url_id: @shorturl.id, bot_user_id: @subscriber.id, clicks_count: "1".to_i)
    end

    @final_url = @card.cta_button_url

    redirect_to @final_url, :status => 301
  end
end

而模型:

代码语言:javascript
复制
class AnalyticClic < ApplicationRecord
  validates_uniqueness_of :bot_user_id, scope: :card_id
end

知道为什么有时我会复制唱片吗?if应该和validates_uniqueness_of一样防止这种情况发生。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-24 22:25:49

首先,我认为您的验证可能需要类似的内容(尽管,TBH,您的语法可能很好):

代码语言:javascript
复制
class AnalyticClic < ApplicationRecord
  validates :bot_user_id, uniqueness: { scope: :card_id }
end

那么,我认为你应该清理一下你的控制器。类似于:

代码语言:javascript
复制
class ShorturlController < ApplicationController
  def show
    @shorturl = ShortUrl.find_by_token(params[:id])
    @card = Card.find(@shorturl.card_id)
    @subscriber = BotUser.find_by_sender_id(params['u'])
    @letter_campaign = Letter.find(@card.letter_id).campaign_name.downcase

    analytic_clic.increment!(:click_count, by = 1)

    @final_url = @card.cta_button_url

    redirect_to @final_url, :status => 301
  end

private

  def analytic_clic
    @analytic_clic ||= AnalyticClic.find_or_create_by(
      card_id: @card.id, 
      short_url_id: @shorturl.id, 
      bot_user_id: @subscriber.id
    )
  end

end 

有几件重要的事情要注意:

您将希望创建一个在数据库级别强制执行唯一性的索引(正如max所说)。我相信这看起来会像:

代码语言:javascript
复制
class AddIndexToAnalyticClic < ActiveRecord::Migration
  def change
    add_index :analytic_clics [:bot_user_id, :card_id], unique: true, name: :index_bot_user_card_id
  end
end

您将希望创建一个迁移,将:click_count设置为create上0的默认值(否则,您将遇到nil问题,我怀疑)。

而且,您需要考虑与increment!的并发性(参见文档)。

票数 2
EN

Stack Overflow用户

发布于 2017-07-24 22:21:42

您需要在数据库表中创建唯一的索引。可能有两个进程一起创建条件。停止这些重复记录的唯一方法是在DB级别上具有唯一性约束。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45290644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档