chiefkikio
chiefkikio

Reputation: 275

No such column for dependent :destroy on has_many, belongs_to relationship

I have a simple has_many, belongs_to association.

class Actor < ActiveRecord::Base
    belongs_to :movie
end

and

class Movie < ActiveRecord::Base
    has_many :actors, dependent: :destroy
    after_save :fill_actors_table
    validates_presence_of :title

    def fill_actors_table
       movie_list = Imdb::Search.new("Lion King")
      new_movie = movie_list.movies.first
      id = new_movie.id

      i = Imdb::Movie.new("#{id}")
      i.cast_members.each do |actor_name|
         actor_image = Google::Search::Image.new(:query => actor_name).first
         actor_image_url = actor_image.uri
         Actor.create(:name => actor_name, :file => actor_image_url)
      end
   end

My schema looks like this:

ActiveRecord::Schema.define(version: 20150821182841) do

  create_table "actors", force: true do |t|
     t.string   "name"
     t.string   "file"
     t.integer  "actor_id",   limit: 255
     t.datetime "created_at"
     t.datetime "updated_at"
   end

  create_table "movies", force: true do |t|
     t.string   "title"
     t.datetime "created_at"
     t.datetime "updated_at"
   end
 end

But I keep getting an error

SQLite3::SQLException: no such column: actors.movie_id: SELECT "actors".* FROM "actors" WHERE "actors"."movie_id" = ?

I don't use movie_id anywhere!!!

Movie Controller Code:

class MoviesController < ApplicationController
  before_action :set_movie, only: [:show, :edit, :update, :destroy]

  # GET /movies
  # GET /movies.json
  def index
    @movies = Movie.all
  end

  # GET /movies/1
  # GET /movies/1.json
  def show
  end

  # GET /movies/new
  def new
    @movie = Movie.new
  end

  # GET /movies/1/edit
  def edit
  end

  # POST /movies
  # POST /movies.json
  def create
    @movie = Movie.find_or_create_by(movie_params)

    respond_to do |format|
      if @movie.save
        format.html { redirect_to @movie, notice: 'Movie was successfully created.' }
        format.json { render :show, status: :created, location: @movie }
      else
        format.html { render :new }
        format.json { render json: @movie.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /movies/1
  # PATCH/PUT /movies/1.json
  def update
    respond_to do |format|
      if @movie.update(movie_params)
        format.html { redirect_to @movie, notice: 'Movie was successfully updated.' }
        format.json { render :show, status: :ok, location: @movie }
  else
        format.html { render :edit }
        format.json { render json: @movie.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /movies/1
  # DELETE /movies/1.json
  def destroy
    @movie.destroy
    respond_to do |format|
      format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_movie
      @movie = Movie.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def movie_params
      params.require(:movie).permit(:title)
    end


end

Actors controller was just generated and really is the same as the movie controller for the most part.


What I'm trying to accomplish: A movie is searched. The movie name is saved in the movie database. Then it pulls a list of actors in the movie using the imdb gem and searches for their images using the google-search gem. The image url's and actor names are saved in the actor database.

I have noticed that when I put in movies, it sometimes seems to list the actors names twice (as if there are two for loops). I can't figure out where I have code that could possibly make it run twice.

This is really the only code I've written in the whole project other than a basic form.

Upvotes: 0

Views: 305

Answers (1)

user1943992
user1943992

Reputation: 222

You need the foreign key in the model with the belongs_to.

When you use:

belongs_to :some_model

rails assumes :some_model_key is in the model. You have no :movie_id in your actors model, so when you try to reference a movie's actors rails looks for the :movie_id in your actor model and can't find it. You can add this column with an active migration.

Upvotes: 1

Related Questions