Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Error Rails Minitest in simple post request

I am facing a very strange problem and I could not find the answer here. I am trying to do simple testing with Minitest in my Rails API application.

I have two simple models one is Movie:

class CreateMovies < ActiveRecord::Migration[7.0]
  def change
    create_table :movies do |t|
      t.string :title
      t.text :synopsis
      t.datetime :launch_date
      t.string :age_classification
      t.string :length
      t.string :genre
      t.string :director
      t.string :poster
      t.decimal :rating_avg

      t.timestamps
    end
  end
end

The other one is Sessions

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class CreateSessions < ActiveRecord::Migration[7.0]
  def change
    create_table :sessions do |t|
      t.references :movie, null: false, foreign_key: true
      t.text :times
      t.text :dates

      t.timestamps
    end
  end
end

Testing "should create session" auto-generated testing function:

class SessionsControllerTest < ActionDispatch::IntegrationTest

  setup do
    @movie = movies(:one)
    @session = sessions(:one)
  end

  test "should create session" do
    assert_difference("Session.count") do
      post sessions_url, params: { session: { dates: @session.dates, movie_id: @session.movie_id, times: '21:00' } }, as: :json
    end

    assert_response 201
  end
end

I face the following error:

Minitest::UnexpectedError: ActiveRecord::RecordInvalid: Validation failed: Movie must exist

movies.yml

one:
  title: Avatar
  synopsis: A paraplegic Marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home
  launch_date: 18/12/2009
  age_classification: +13
  length: 162
  genre: Action
  director: James Cameron
  poster: https://m.media-amazon.com/images/M/MV5BNjA3NGExZDktNDlhZC00NjYyLTgwNmUtZWUzMDYwMTZjZWUyXkEyXkFqcGdeQXVyMTU1MDM3NDk0._V1_SX300.jpg
  rating_avg: 8.0

sessions.yml

one:
  movie: one
  times: 16:00
  dates: 17/07/2022

I have ensured Movie exists when post line is executing but no clue why is this happening. Any ideas?

PD: Running on Ruby 3.1.2 and Ruby On Rails 7.0.4

I tried to forcefully create a new Movie just before the post statement it did not work. I also tried to output if the movie exists inside controller when it creates the session but it does not save the session because ActiveRecord::RecordInvalid: Validation failed: Movie must exist.

>Solution :

Your parameters are nested under session in the request, but your strong parameter method doesn’t reflect this nesting.

Change your session_params method to:

def session_params
  params.require(:session).permit(:movie_id, :times, :dates)
end

When you parameters look like this

params = { session: { dates: @session.dates, movie_id: @session.movie_id, times: '21:00' } }

and you only call params.permit(:movie_id, :times, :dates) then Rails would try to permit those key/value pairs on the other hash. Because those keys do not exist on the outer hash but only on the inner hash params.permit(:movie_id, :times, :dates) will return an empty {} hash.

But when you call params.require(:session).permit(:movie_id, :times, :dates), then the require(:session) will require that there is a session key on the outer hash and will return its inner hash. Then the chained permit(:movie_id, :times, :dates) call will permit those key/value pairs from the inner hash and will return:

{ dates: @session.dates, movie_id: @session.movie_id, times: '21:00' }

I suggest reading about strong parameters in the official Rails Guides.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading