Peter Boomsma
Peter Boomsma

Reputation: 9806

Add multiple user id's to one record

I have a database with a movie table in it,

create_table "movies", force: :cascade do |t|
  t.string   "title"
  t.string   "release_date"
  t.string   "image"
  t.integer  "user_id"
  t.datetime "created_at",   null: false
  t.datetime "updated_at",   null: false
  t.string   "movie_id"
end

At the moment when a user adds a new movie to his watchlist a new record is create, even if that movie is allready in the database.

So for example 3 users all add the new Star Wars movie to their watchlist, my database will have 3 different records of that Star Wars movie and with 3 different user id's.

What I'm looking for is a way to check if a movie already exists in my database, if so only add the user id to the user id column of that movie record. So that users share the movie record.

Also on removal users should not remove the whole record, but only their user id from the user id column of that movie record.

I'm using Angular so this is my addMovie function in my controller,

    movieAdd.add()
      .then(function(response){
        $scope.movieListID = response;
        console.log ('Not empty' + $scope.movieListID)

        for (var i = 0; i < $scope.movieListID.releases.countries.length; i++) {
          var release = $scope.movieListID.releases.countries[i];
          if (release['iso_3166_1'] == 'NL') {
              releaseNL = release;
          }
        }

        if(typeof releaseNL === 'undefined'){
          // With release date

          Notification($scope.movieListID.original_title + ' is toegevoegd, maar heeft nog geen Nederlandse premiere datum.');

          createMovie.create({
            title:          $scope.movieListID.original_title,
            release_date:   $scope.movieListID.release_date,
            image:          $scope.movieListID.poster_path,
            movie_id:       $scope.movieListID.id
          }).then(init);

        } else {
          Notification.success($scope.movieListID.original_title + ' is toegevoegd.');

          createMovie.create({
            title:          $scope.movieListID.original_title,
            release_date:   releaseNL.release_date,
            image:          $scope.movieListID.poster_path,
            movie_id:       $scope.movieListID.id
          }).then(init);
        };

      })
      .catch(function(response) {
        console.log ('No search response')
      });

  }

And this is the RoR controller,

def create
  respond_with Movie.create(movie_params.merge(user_id: current_user.id))
end

Upvotes: 0

Views: 292

Answers (1)

chumakoff
chumakoff

Reputation: 7044

If you use a relational DB, such as PostgreSQL or MySQL, it is a good practise in your case to have 3 tables: movies, users and the third one which is for storing links between movies and users. This type of association is called many-to-many. This will eliminate the duplication of the movies records in the DB.

create_table "movies" do |t|
  t.string   "title"
  ....
  # no user_id column
end

create_table "users" do |t|
  t.string   "name" # for example
  ...
end

create_table "movies_users" do |t|
  t.integer "user_id"
  t.integer "movie_id"
end

In this case, if a user wants to share a movie then one movies_users record is created which connects the user with the movie.

I didn't answer your question, but I highly recommend you to think of what I said.

You can read more about associations here http://guides.rubyonrails.org/association_basics.html

Edited (added controller action example):

def create
   movie = Movie.create(movie_params)
   current_user.movies << movie
   ...
end

or like this:

def create
   current_user.movies.create(movie_params)
   ...
end

In both cases the third table record (movies_users) will be created automatically.

Upvotes: 1

Related Questions