1

I am trying to build nested routes and as mentioned here I m trying to edit my boat picture as <%= link_to "edit", edit_boat_picture_path(@boat, picture) %>. But when I try it, it throws an error undefined local variable or methodpicture' for #<#:0x007f9637811ee0>`

my picture controller is; (probably destroy is wrong also)

class PicturesController < ApplicationController
  before_action :logged_in_user
  before_filter :load_parent

  def index
    @picture = @boat.pictures.all
  end

  def new
    @picture = @boat.pictures.new
  end

  def show
    @pictures = @boat.pictures.find(params[:id])
  end


  def create

    @picture = @boat.pictures.new(picture_params)
    if @picture.save
      #flash[:success] = "Continue from here"
      render 'show'
    else
      render 'new' 
    end
  end

  def edit
    @picture = Picture.find(params[:id])
  end

  def update
    @picture = @boat.pictures.find(params[:id])

    if @picture.update_attributes(picture_params)
      flash[:notice] = "Successfully updated picture."
      render 'show'
    else
      render 'edit'
    end
  end

  def destroy

    @picture = @boat.pictures.find(params[:id])
    @picture.destroy
    flash[:notice] = "Successfully destroyed picture."
    redirect_to @picture.boat
  end


  private

    def picture_params
      params.require(:picture).permit(:name, :image)
    end

    def load_parent
     @boat = Boat.find(params[:boat_id])
    end

end

1 Answer 1

2

Presumably you should change

<%= link_to "edit", edit_boat_picture_path(@boat, picture) %>

to

<%= link_to "edit", edit_boat_picture_path(@boat, @picture) %>

The key there being changing picture to @picture. The reason to do this is that you're declaring @picture (an instance variable) in your controller, not picture (a local variable). When declaring and defining an instance variable in a method in your controller, it's also accessible in the corresponding view. However, when declaring a local variable in a method in your controller, it is not available in your view.

So even if you had declared picture rather than @picture in your controller method, it wouldn't be accessible in your view, since it's a local variable.

For more information on the five types of ruby variables, see this link.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes it works that way, I tried. But did not understand the logic behind it.
I edited my answer to add some explanation, does it help at all?
You defined @picture in the controller's action, but you were trying to acces to the picture variable, which does not exist. @variables are shared between the controller's action(s) and the view(s), whereas variables are just local variables, only existing in the local context (controller's action OR a single view OR a single block, etc.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.