I want to run the update action, but I can't get the ID. I thought it would be a simple problem, but I could not find a solution to the problem.
I thought the value sent from edit would be sent to the update action and the update action would update the value, but I can't get the ID. I've been looking at other articles and it looks like it's updating in the same way.
Code
edit
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<%= form_with model: @movie, url: '/admin/movies/:id', method: :put do |form| %>
<%= form.text_field :name %>
<p>Year</p>
<%= form.text_field :year %>
<p>Image URL</p>
<%= form.text_field :image_url %>
<p>Description</p>
<%= form.text_area :description %>
<p>Show</p>
<%= form.text_field :is_showing %>
<%= form.submit"Edit Save"%>
<% end %>
</body>
</html>
controller
class MoviesController < ApplicationController
def index
@movie = Movie.all
end
def new
@movie = Movie.new
end
def create
@movie = Movie.new(post_params)
@movie.save!
end
def edit
@movie = Movie.find(params[:id])
@movie.save
end
def update
@movie = Movie.find(params[:id])
if @movie.update(post_params)
redirect_to :idnex
else
render :edit
end
end
private
def post_params
params.require(:movie).permit(:id,:name, :year, :image_url, :description, :is_showing )
end
end
model
FactoryBot.define do
factory :movie do
sequence(:name) { |n| "TEST_MOVIE#{n}"}
sequence(:year) { 2021 }
sequence(:description) { "test"}
sequence(:image_url) {"" }
sequence(:is_showing) { 1 }
end
end
routes
Rails.application.routes.draw do
# get 'movies', to: 'movies#index'
get '/admin/movies', to: 'movies#index'
get '/admin/movies/new', to: 'movies#new'
post '/admin/movies/new', to: 'movies#create'
get '/admin/movies/:id/edit', to: 'movies#edit'
put '/admin/movies/:id', to: 'movies#update'
get '/admin/movies/:id', to: 'movies#edit'
end
Error after changing form_with method
CodePudding user response:
You really just need to leverage the rails conventions here instead of doing everything manually.
Rails.application.routes.draw do
scope :admin do
resources :movies
end
end
Instead of manually typing out each route use the resources
macro. Also Rails has used the PATCH HTTP method instead of PUT for updates for quite some time. For legacy reasons Rails will output a PUT route as well but that may change in the future.
Now the form:
<%= form_with model: [:admin, @movie] do |form| %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :year %>
<%= form.text_field :year %>
</div>
<div class="field">
<%= form.label :image_url, "Image URL" %>
<%= form.text_field :image_url %>
</div>
<div class="field">
<%= form.label :description %>
<%= form.text_area :description %>
</div>
<div class="field">
<%= form.label :is_showing, "Show" %>
<%= form.text_field :is_showing %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
You do not need to specify the URL or the method. Rails can figure all that out just based on the model. Using [:admin, @movie]
tells rails to look for admin_movie_path
.
Use labels instead of <p>
tags to label your inputs so that its accessible to assistive technologies like screen readers. Grouping the input and label together in an element lets you style it with CSS.
Your controller has numerous typos and errors in it:
class MoviesController < ApplicationController
# GET /admin/movies
def index
# use the plural name for the instance variable since its many movies
@movies = Movie.all
end
# GET /admin/movies/new
def new
@movie = Movie.new
end
# POST /admin/movies/
def create
@movie = Movie.new(post_params)
# check if the movie is saved and respond accordingly
# save! generally should not be used in controllers
if @movie.save
redirect_to :index, notice: 'Movie created'
else
render :new
end
end
# GET /admin/movies/1/edit
def edit
@movie = Movie.find(params[:id])
end
# PATCH|PUT /admin/movies/1
def update
@movie = Movie.find(params[:id])
if @movie.update(post_params)
# this was a typo
redirect_to :index, notice: 'Movie updated'
else
render :edit
end
end
private
def post_params
params.require(:movie)
.permit(
:id, :name, :year,
:image_url, :description, :is_showing
)
end
end