Ask A Question

Notifications

You’re not receiving notifications from this thread.

How can I solve it?

Federico Calarco asked in General

Hello guys I have a problem with this!

I'm making my website where user can give feedback to my projects, contact me and make comment to a blog_post.
The problem is when i make the render 'blog_posts/form' the errors are
"First argument in form cannot contain nil or be empty" - (@blog_post) ( solvable with -BlogPost.new-)
the second error after that is
"undefined method `errors' for nil:NilClass" - <% if @blog_post.errors.any? %>

If i remove the block with the if statement for errors everything will work but there will be no parsing error after the create/new action (I set up the validations of the presence of name and content in the model )
I'm waiting for your help , thank you

Reply

<div class="col-sm-6 col-sm-offset-3"  >
  <div class="modal fade " id="myModal" tabindex="-1" role="dialog">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
          <h4 class="modal-title">Modal title</h4>
          <%= form_for(BlogPost.new) do |f| %>
            <% if @blog_post.errors.any? %>
              <div id="error_explanation">
                <h2><%= pluralize(@blog_post.errors.count, "error") %> prohibited this blog_post from being saved:</h2>

                <ul>
                <% @blog_post.errors.full_messages.each do |message| %>
                  <li><%= message %></li>
                                        <div class="col-sm-2  pull-left" id="socialize">
                                <p>I'm a social persons find me :<br>fb tw insta</p>

                                        </div>

                <% end %>
                </ul>
              </div>
            <% end %>

            <div class="field">
              <%= f.label :title %><br>
              <%= f.text_field :title %>
            </div>
            <div class="field">
              <%= f.label :description %><br>
              <%= f.text_area :description %>
            </div>
            <div class="field">
              <%= f.label :status %><br>
              <%= f.check_box :status %>
            </div>
            <div class="field">
              <%= f.label :category %><br>
              <%= f.text_field :category %>
            </div>
            <div class="field">
              <%= f.label :post_date %><br>
              <%= f.date_select :post_date %>
            </div>
            <div class="actions">
              <%= f.submit %>
            </div>
          <% end %>

        </div>
        <div class="modal-body">
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->
</div>


            </div>
Reply

I tried to copy and past the code block but it doesn't work

Reply

For code blocks, you can write backticks ` around your content so that it shows up as code and doesn't get eaten. :)

```
code
```

Sounds like you just need to set your @blog_post variable in your controller action. Have you set that? You'll also need to modify your form_for to be form_for(@blog_post) to be consistent.

@blog_post = BlogPost.new

Reply

I thought the same thing and I immediately wrote the code in the controllers but it still does not work , I really don't know where is my error

Reply

What does your controller look like?

Reply

class BlogPostsController < ApplicationController
  before_action :set_blog_post, only: [:show, :edit, :update, :destroy]



  # GET /blog_posts
  # GET /blog_posts.json
  def index
    @blog_posts = BlogPost.all

  end

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

  # GET /blog_posts/new
  def new
    @blog_post = current_admin.blog_posts.new
  end

  # GET /blog_posts/1/edit
  def edit
  end

  # POST /blog_posts
  # POST /blog_posts.json
  def create

    @blog_post = current_admin.blog_posts.new(blog_post_params)

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

  end

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

  # DELETE /blog_posts/1
  # DELETE /blog_posts/1.json
  def destroy
    @blog_post.destroy
    respond_to do |format|
      format.html { redirect_to blog_posts_url, notice: 'Blog post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def blog_post_params
      params.require(:blog_post).permit(:title, :description, :status, :category, :post_date)
    end
end

The render ( of the form ) is inside a modal in /layouts/application.html.erb
Should I declare the variable in other controller?

Reply

Ah! So if you've got it on the application layout, that means you need to set the @blog_post variable on every page. You've got two approaches for this.

  1. You can create a before_action :set_blog_post on ApplicationController so it runs on every action.
  2. Or I realized you could modify your form like this (I'd recommend this approach in this case):
          <%= form_for(BlogPost.new) do |f| %>
            <% if f.object.errors.any? %>
              <div id="error_explanation">
                <h2><%= pluralize(@f.object.errors.count, "error") %> prohibited this post from being saved:</h2>

                <ul>
                <% f.object.errors.full_messages.each do |message| %>
                  <li><%= message %></li>
                                        <div class="col-sm-2  pull-left" id="socialize">
                                <p>I'm a social persons find me :<br>fb tw insta</p>

                                        </div>

                <% end %>
                </ul>
              </div>
            <% end %>

            <div class="field">
              <%= f.label :title %><br>
              <%= f.text_field :title %>
            </div>
            <div class="field">
              <%= f.label :description %><br>
              <%= f.text_area :description %>
            </div>
            <div class="field">
              <%= f.label :status %><br>
              <%= f.check_box :status %>
            </div>
            <div class="field">
              <%= f.label :category %><br>
              <%= f.text_field :category %>
            </div>
            <div class="field">
              <%= f.label :post_date %><br>
              <%= f.date_select :post_date %>
            </div>
            <div class="actions">
              <%= f.submit %>
            </div>
          <% end %>

What I did here was change @blog_post to f.object which is a reference to the BlogPost.new that you passed into the form_for originally. This way you won't need the @blog_post variable at all.

Reply

OOOOOOK , it works , but now if I write an empty blog_post there are no error like " title can't be blank" , it's a half success :D

Reply

Yeah, when you use BlogPost.new, that's creating a new object without errors, so those obviously won't exist on a new one.

One solution is to go in your app/views/blog_posts/new.html.erb you'll want to make sure you use @blog_post so that it has the errors when it renders. This way it will try to save, when it fails, it will render blog_posts/new and you'll have the errors on the @blog_post object that you can render.

The other alternative would be to submit the form with JS and use that to display the errors.

Reply

Perfect , I will search how to do that, thank you!

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 76,990+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2023 GoRails, LLC. All rights reserved.