GaoVN
GaoVN

Reputation: 33

Getting "param is missing or the value is empty: post" explained below

when i click new post and try to save a new post it gives me that error, then i go to the controller :

private
  def posts_params
    params.require(:post).permit(:title, :description)
  end

and change 'require(:post)' to 'require(:posts' then i works but then i try to edit the new post i just created and when i click to save it it gives me the same error, then i just change it back to 'required(:post)' and it works, why this is happening ? it's like a loop, if one works the other doesn't and to work i have to change that one thing

Controller:

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end

  def edit
    @posts = Post.find(params[:id])
  end

  def update
  @posts = Post.find(params[:id])

  if @posts.update(posts_params)
    redirect_to @posts
  else
    render 'edit'
  end
end

  def new
    @posts = Post.new
  end

  def create
      @posts = Post.new(posts_params)
    if @posts.save
        redirect_to @posts
    else
        render 'new'
    end
  end

  def show
    @posts = Post.find(params[:id])
  end

  private
  def posts_params
    params.require(:post).permit(:title, :description)
  end


end

view edit:

<h1>Editing post</h1>

<%= form_for(@posts)  do |f| %>

  <% if @posts.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@posts.errors.count, "error") %> prohibited
        this post from being saved:
      </h2>
      <ul>
        <% @posts.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </p>

  <p>
    <%= f.submit %>
  </p>

<% end %>

<%= link_to 'Back', posts_path %>

view new:

<h1>New Article</h1>
<%= form_for :posts, url: posts_path do |f| %>
<% if @posts.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@posts.errors.count, "error") %> prohibited
        this post from being saved:
      </h2>
      <ul>
        <% @posts.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>
<%= link_to 'Back', posts_path %>

can someone point the problem out ?

Upvotes: 0

Views: 127

Answers (1)

Doon
Doon

Reputation: 20232

You are mixing

form_for(@posts)  do |f| 

and

 form_for :posts, url: posts_path 

In your forms.

the :posts version will generate params[:posts] and the @posts version will generate params[:post]. Hence the issue you are seeing. Make sure you posts_params is as follows.

def posts_params
  params.require(:post).permit(:title, :description)
end

then just change both of your forms to be

<%= form_for(@posts) do |f| %>

rails will figure out which to call automatically for you, so you will not have to specify the paths..

On a side note, I would probably change @posts to be @post everywhere but the index action, just so that it makes more sense, Since in new,edit,etc.. you are dealing with a singular post.

Since rails is looking at the Model/class of the variable when generating the routes (When given an instance variable) the name of the variable doesn't matter to the framework, but makes it easier (in my opinion) for the programmer to understand

Upvotes: 1

Related Questions