0

このような類似の質問がたくさんありますが、私にとって良い答えが見つかりませんでした。

私は fields と他のいくつかのモデルを持っていEntryVoteます。user_identry_id

user_id、グループの重複を削除する単純なrakeタスクを作成したいentry_id(グループからどのレコードが残っているかは関係ありません)。それを行う最良の方法は何ですか?

例えば:

id, user_id, entry_id
1,1,1
2,1,1
3,1,1
4,5,6
5,5,6
6,7,7

私は得る:

1,1,1
4,5,6
6,7,7 

重複排除のために user_id、entry_id を選択する方法は知っていますが、その後の操作方法がわかりません。

EntryVote.select('user_id, entry_id').group('user_id,entry_id').having('count() > 1')

4

2 に答える 2

0

そこにある最善の解決策ではないかもしれませんが、次のことを試してください

EntryVote.count(:id, group: [:user_id, :entry_id]).each do |(user_id, entry_id), count|
  if count > 1
    EntryVote.offset(1).where(user_id: user_id, entry_id: entry_id).delete_all
  end
end

または、user_idとentry_idの一意性をチェックする検証を追加して、レコードの保存を試みることができます。レコードが保存されず、検証のために失敗した場合は、レコードを削除するだけです。私はこれが最初のオプションより遅いとかなり確信しています:)

于 2013-03-05T12:36:09.710 に答える
0

entry_id列を一意の外部キーにしたい場合user_idは、特別な SQL 削除ステートメントを含む次の rake タスクが役立ちます

  task 'delete_duplicates' => :environment do
    puts "Removing duplicates in table entry_votes"
    puts "Entries before: #{n1=EntryVote.count}"
    sql = "delete e1 from entry_votes e1, entry_votes e2 "+
          "where (e1.user_id = e2.user_id) and (e1.entry_id = e2.entry_id) "+
          "and (e1.id > 12.id);")
    ActiveRecord::Base.connection.execute(sql);
    puts "Entries after: #{n2=EntryVote.count}, #{n1-n2} duplicates removed"
  end

this SO question about duplicatesまたは this article how to delete duplicates using SQLも参照してください。

于 2013-03-05T14:43:19.597 に答える