Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby Advanced Social Features in Ruby on Rails Create an Image Gallery Listing Pictures

NoMethodError in PicturesController#new

Hi,

I have this problem (with Rails 4 / ruby2.0) when I want to add a picture:

NoMethodError in PicturesController#new undefined method `portfolios' for nil:NilClass

Extracted source (around line #76):

def find_portfolio
    @portfolio = @user.portfolios.find(params[:portfolio_id])
end

Parameters:

{"username"=>"1", "portfolio_id"=>"7"}

pictures_controller.rb:

class PicturesController < ApplicationController
  before_filter :authenticate_user!, only: [:new, :create, :edit, :update, :destroy]
  before_filter :find_user
  before_filter :find_portfolio

  # GET /pictures
  # GET /pictures.json
  def index
    @pictures = @portfolio.pictures.all
  end

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

  # GET /pictures/new
  def new
    @picture = @portfolio.pictures.new
  end

  # GET /pictures/1/edit
  def edit
  end

  # POST /pictures
  # POST /pictures.json
  def create
    @picture = @portfolio.pictures.new(picture_params)

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

  # PATCH/PUT /pictures/1
  # PATCH/PUT /pictures/1.json
  def update
    respond_to do |format|
      if @picture.update(picture_params)
        format.html { redirect_to @picture, notice: 'Picture was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @picture.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /pictures/1
  # DELETE /pictures/1.json
  def destroy
    @picture.destroy
    respond_to do |format|
      format.html { redirect_to pictures_url }
      format.json { head :no_content }
    end
  end

  def url_options
    { username: params[:username] }.merge(super)
  end

  private   
    def find_user
      @user = User.find_by_username(params[:username])
    end

    def find_portfolio
        @portfolio = @user.portfolios.find(params[:portfolio_id])
    end

    def find_picture
      @picture = @porfolio.pictures.find(params[:id])
    end
    def picture_params
      params.require(:picture).permit(:caption, :description, :portfolio_id, :user_id)
    end
end

form.html.erb:

<%= simple_form_for(@portfolio, @picture), html: { class: 'form-horizontal'} do |f| %>
  <% if @picture.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@picture.errors.count, "error") %> prohibited this picture from being saved:</h2>

      <ul>
      <% @picture.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>


  <div class="form-inputs">
    <%= f.input :caption %>
    <%= f.input :description %>
  </div>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

I modified picture_params but nothing work!

Thanks for your help.

Fabrice

1 Answer

Hi Fabrice,

I think that your private method "find_user" is using a deprecated method. Instead of:

def find_user
  @user = User.find_by_username(params[:username])
end

try:

def find_user
  @user = User.find_by(username: params[:username])
end

Hope this helps

Mikal