kai
kai

Reputation: 492

Rails 4 - Insert duplicate ActiveRecord data

I developed pointing some object and below is my code.

if ObjectRating.where(user_id: current_user.id, object_id: @object.id).present?
    rating = ObjectRating.where(user_id: current_user.id, object_id: @object.id).first
    if rating.update_attributes(rating_params)
      @jsonResult.object = rating
    else
      @jsonResult.status = false
      @jsonResult.message = "Please Retry"
    end 
  else
    rating = @object.object_ratings.new(rating_params)
    rating.user_id = current_user.id

    if rating.save
      @jsonResult.object = rating
    else
      @jsonResult.status = false
      @jsonResult.message = "Please Retry"
    end 
  end 

Rating params is

private
def rating_params
  params.require(:object_rating).permit(:rating)
end

It works good but sometime insert duplicate data in to database.


+----------------------------------------------------------+
| id, object_id , user_id, rating, created_at, updated_at  |
+----------------------------------------------------------+
| 1, 100, 200, 8 ,2015-06-26 10:52:34, 2015-06-26 10:52:48 |
| 2, 100, 200, 8 ,2015-06-26 10:52:34, 2015-06-26 10:52:34 |
| 3, 120, 230, 8 ,2015-06-26 10:54:32, 2015-06-26 10:54:32 |
+----------------------------------------------------------+

ID 1, 2 is same object .

I checked before save in controller, Why it create duplicate record for the next one?

Upvotes: 1

Views: 539

Answers (4)

You could try something like this:

...
else
    rating = ObjectRating.new(rating_params)
    rating.user_id = current_user.id
...

Why? How many an objects will be create when @object.object_ratings.new? Sometime it will possible creating Object.new(object_raing.params) and Object_ratings.new(params) both (or triple).

Upvotes: 0

jon snow
jon snow

Reputation: 3072

you could add indexing of following columns object_id , user_id, rating. Create migration like,

add_index :object_ratings, [:object_id , :user_id, :rating], unique: true

Upvotes: 1

sameera207
sameera207

Reputation: 16629

All the ruby objects are inherited from the class Object directly or indirectly

Ex:

String.superclass -> Object < BasicObject

and every object has its object id

ObjectRating.object_id -> <some lenghthy number>

So when you search for object_id it actually search for base object id and hence you always gets results as not found

then as per your code, you save the record again.

My advice is to get rename the column ‘object_id’ in to something else (not to conflict with ruby/rails internals)

Upvotes: 1

Rubyrider
Rubyrider

Reputation: 3587

You can try uniqueness validation with scope.

validates :uniqueness => { scope: [:user_id, :object_id] }

Upvotes: 1

Related Questions