Steez
Steez

Reputation: 229

Active Record Associations to prevent duplicate database entries

I am setting up a Ruby on Rails application where a User will have an Album collection. My initial thinking was to set it up with a simple User has_many Albums and Albums belongs to Users. The problem that arises here is that the Album table will have duplicates entries, only distinguished by user_id.

id  | album_name  | artist_id |         created_at         |         updated_at         | user_id 
-----+-------------+-----------+----------------------------+----------------------------+---------
   2 | SuperRando |   3       | 2015-11-13 00:03:51.790759 | 2015-11-13 00:03:51.790759 |  1       
   3 | SuperRando |   3       | 2015-11-13 00:19:08.438907 | 2015-11-13 00:19:08.438907 |  2      

So what would be the best course of action so I could have an Album table with all unique albums?

Upvotes: 0

Views: 327

Answers (1)

CuriousMind
CuriousMind

Reputation: 34135

You could model it using a join table:

class Album < ActiveRecord::Base
  has_many :user_albums
  has_many :users, through: :user_albums
end

class User < ActiveRecord::Base
  has_many :user_albums
  has_many :albums, through: :user_albums
end

class UserAlbum < ActiveRecord::Base
  belongs_to :user
  belongs_to :album
end

So, your schema would like somewhat like this:

create_table "albums", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "user_albums", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "album_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string   "email"
    t.string   "first_name"
    t.string   "last_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Now, the way you would call this code in your controller or console. you can do this:

  1. Create User: user = User.create(params)
  2. Find or Create an album: album = Album.find_or_create_by(params)
  3. Associate user with that album user.albums << album & then save it by user.save

Now to see user's album. you can do: User.take.albums

to see users of a particular album, you can do Album.take.users

Hope this answers your question.

For more information have a look at the rails guides: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Upvotes: 3

Related Questions