J Seabolt J Seabolt - 18 days ago 5
Ruby Question

Ruby on Rails form error

I am building an app from an online tutorial. It tracks "Movies" and "Rentals." I am trying to set up the part where you create a new rental. When I submit the form, I get this error:

ActiveModel::ForbiddenAttributesError in RentalsController#create


Here is the full rentals controller:

class RentalsController < ApplicationController

def new
@movie = Movie.find(params[:id])
@rental = @movie.rentals.build
end

def create
@movie = Movie.find(params[:id])
@rental = @movie.rentals.build(params[:rental])
if @rental.save
redirect_to new_rental_path(:id => @movie.id)
end
end
end


It seems to take issue with this line in particular:

@rental = @movie.rentals.build(params[:rental])


Here is the Rental model:

class Rental < ApplicationRecord
has_one :movie
end


Here is the controller for Movies:

class MoviesController < ApplicationController

def new
@movie = Movie.new
@movies = Movie.all
end

def create
@movie = Movie.new(movie_params)
if @movie.save
redirect_to new_movie_path
end
end

private

def movie_params
params.require(:movie).permit(:title, :year)
end
end


Here is the Movie model:

class Movie < ApplicationRecord
has_many :rentals
end


Here are the routes:

Rails.application.routes.draw do
resources :movies, :rentals
root 'movies#new'

end


Here is the form:

<h1><%= @movie.title %></h1>

<%= form_for @rental, :url => {:action => :create, :id => @movie.id } do |r| %>
Borrowed on: <%= r.text_field :borrowed_on %><br />
Returned on: <%= r.text_field :returned_on %><br />
<br />
<%= r.button :submit %>
<% end %>
<br />
<%= link_to "back", new_movie_path %>


I'm not sure what is going on. From what I can tell, I am copying the tutorial exactly. Any help would be much appreciated!

Answer

You aren't using strong params for rentals, hence the ActiveModel::ForbiddenAttributesError error.


This should fix the error:

class RentalsController < ApplicationController

  def new
    @movie = Movie.find(params[:id])
    @rental = @movie.rentals.build
  end

  def create 
    @movie = Movie.find(params[:id])
    @rental = @movie.rentals.build(rental_params)
    if @rental.save 
        redirect_to new_rental_path(:id => @movie.id)
    end
  end

  private

  def rental_params
    params.require(:rental).permit(:borrowed_on, :rented_on)
  end
end