Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

James Home
James Home
12,011 Points

undefined method `each' for nil:NilClass outside typical controller

I want to display a list of posts on the homepage. It works locally but when I push it to Heroku it provides an error: "undefined method `each' for nil:NilClass outside typical controller". It also works locally and on Heroku on the show.erb. Anyone have an idea? :(

Welcome Controller

class WelcomeController < ApplicationController

  # GET /welcome
  def index
    @posts = Post.all
  end

end

Post Model

class Post < ActiveRecord::Base
  #This validates presence of title, and makes sure that the length is not more than 140 words
  validates :title, presence: true, length: {maximum: 140}
  #This validates presence of body
  validates :body, presence: true
  # Add friendly id to replace {#:id} for post url
  extend FriendlyId
   friendly_id :title, use: [:slugged, :finders]
   # Sort by created_date (not via database, static)
   scope :recent, -> { order(created_at: :desc) }
   scope :last_three, -> { order(created_at: :desc).limit(4) }

   has_one_attached :header_image

end

Post Controller

class PostsController < ApplicationController
  before_action :find_post, only: [:edit, :update, :show, :destroy]
  before_action :authenticate_admin!, except: [:index, :show]

  # Index action to render all posts
  def index
    @posts = Post.all.recent
  end

  # Action to create new post
  def new
    @post = Post.new
  end

  # Action to save post in database

  def create

    @post = Post.create!(post_params)
    @post.save!

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

  end

  # Action to retrieve post and render edit page
  def edit
    @post = Post.find(params[:id])
  end

  # Action to update post with new information
  def update

    @post = Post.find(params[:id])
    if @post.update(post_params)
      flash[:notice] = "Updated post"
      redirect_to post_path(@post)
    else
      flash[:alert] = "Error updating post!"
      render :edit
    end

  end

  # Action render individual post after retrieval
  def show
    @post = Post.find(params[:id])
  end

  # Action to destroy post from database (perma)

  def destroy

    if @post.destroy
      flash[:notice] = "Post deleted success"
      redirect_to posts_path
    else
      flash[:alert] = "Error update post"
    end

  end

    private

    def post_params
      params.require(:post).permit(:title, :body, :header_image)
    end

    def find_post
      @post = Post.find(params[:id])
    end

end

welcome/index.erb (@post loop)

    <% @posts.each do |post| %>
      <div class="tile relative">
        <div class="br1 overflow-hidden mb4 shadow-4">
          <% if post.header_image.attached? %>
            <%= image_tag(post.header_image, :class => "db-ns dn w-100") %>
          <% end %>
          <div class="pa3 bg-white">
            <h3 class="mt0"><%= post.title %></h3>
            <p><%= raw(post.body).truncate(358)%></p>
            <%= link_to "Learn More", post_path(post), class: "no-underline red dim bg-white inline-flex items-center mb2" %>
          </div>
          <% if admin_signed_in? %>
          <%= link_to "Edit", edit_post_path(post), class: "f6 link ph3 pv2 mb2 dib white bg-dark-blue bg-animate hover-bg-light-blue absolute top-0 right-0" %>
          <% end %>
        </div>
      </div>
      <% end %>

posts/show.erb

<% if @post.header_image.attached? %>

<section class="cover bg-center pv5 ph5-ns ph4 mt4" style="background-image:url('<%= rails_blob_url(@post.header_image) %>')">
  <div class="tc white">
    <h1 class="f1 lh-title" style="margin: auto;"><%= @post.title %></h1>
    <span><%= @post.created_at.strftime('%b %d, %Y') %></span>
  </div>
</section>
<% else %>
<section class="cover bg-bottom pv5 ph5-ns ph4 mt4 flex" style="background-image:url('https://source.unsplash.com/le5_KDf5x7s/1600x900')">
  <h1 class="f1 lh-title tc white" style="margin: auto;"><%= @post.title %></h1>
</section>

<% end %>

<section class="pv5 ph5-ns ph4">
  <div class="mwc">
    <%= raw @post.body %>
  </div>
</section>


<section class="ph5-ns ph4">
  <div class="mwc">
    <% if admin_signed_in? %>
      <%= render "partial/adminbar" %>
    <% end %>  </div>
</section>

1 Answer

James Home
James Home
12,011 Points

Yes, and db:seed. In the end I ended up doing the @post inside the view itself and it worked:

      <% Post.all.each do |post| %>
        <div class="tile relative">
          <div class="br1 overflow-hidden mb4 shadow-4">
            <% if post.header_image.attached? %>
              <%= image_tag(post.header_image, :class => "db-ns dn w-100") %>
            <% end %>
            <div class="pa3 bg-white">
              <h3 class="mt0"><%= post.title %></h3>
              <p><%= raw(post.body).truncate(358)%></p>
              <%= link_to "Learn More", post_path(post), class: "no-underline red dim bg-white inline-flex items-center mb2" %>
            </div>
            <% if admin_signed_in? %>
              <%= link_to "Edit", edit_post_path(post), class: "f6 link ph3 pv2 mb2 dib white bg-dark-blue bg-animate hover-bg-light-blue absolute top-0 right-0" %>
            <% end %>
            </div>
          </div>
        <% end %>

I am still curious why it wasn't picking up from the controller. Did it get the two @post mixed up?