Edit a story (shovell)

Hi!

I’m just asking to save some time if someone has done this already namely new action for Story to edit a story.

Pointers in the right direction are welcome. I was thinking of borrowing the concept from “shove it” button with Ajax but then decided that with my level of understanding I am better off changing the behaviour of creating a new story to suit the needs of editing instead. Then there is deleting a specific Story. Both require links beside the story name in the _story partial as I understand it.

Thanks in advance!

It’s been a while since I fooled with RoR. But AFAIK RoR takes care of the CRUD. So if you have “update” call “edit” it should work.

These are from other tutorials (I linked to them in this forum’s sticky thread) and might help

edit.html.erb

<h1>Edit Book Detail</h1>
<% form_tag :action => 'update', :id => @book do %>
<p><label for="book_title">Title</label>:
<%= text_field 'book', 'title' %></p>
<p><label for="book_price">Price</label>:
<%= text_field 'book', 'price' %></p>
<p><label for="book_subject">Subject</label>:
<%= collection_select(:book, :subject_id,
                         @subjects, :id, :name) %></p>
<p><label for="book_description">Description</label><br/>
<%= text_area 'book', 'description' %></p>
<%= submit_tag "Save changes" %>
<% end %>
<%= link_to 'Back', {:action => 'list' } %>

book_controller.rb

class BookController < ApplicationController
   layout 'standard'
   def list
      @books = Book.find(:all)
   end
    
   def show
      @book = Book.find(params[:id])
   end
   
   def new
      @book = Book.new
      @subjects = Subject.find(:all)
   end
   
   def create
      @book = Book.new(params[:book])
      if @book.save
            redirect_to :action => 'list'
      else
            @subjects = Subject.find(:all)
            render :action => 'new'
      end
   end
   
   def edit
      @book = Book.find(params[:id])
      @subjects = Subject.find(:all)
   end
   
   def update
      @book = Book.find(params[:id])
      if @book.update_attributes(params[:book])
         redirect_to :action => 'show', :id => @book
      else
         @subjects = Subject.find(:all)
         render :action => 'edit'
      end
   end
   
   def delete
      Book.find(params[:id]).destroy
      redirect_to :action => 'list'
   end
    
   def show_subjects
      @subject = Subject.find(params[:id])
   end
end

and:

edit.html.erb

<h1>Editing movie</h1>

  <%= error_messages_for :movie %>

<% form_for(@movie) do |f| %>
  <%= render :partial => 'form', :locals => { :f => f, :label_text => 'Update'} %> 
<% end %>

<%= link_to 'Show', @movie %> |
<%= link_to 'Back', movies_path %>

movies_controller.rb

class MoviesController < ApplicationController
  # GET /movies
  # GET /movies.xml
  def index
    @movies = Movie.find(:all)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @movies }
    end
  end

  # GET /movies/1
  # GET /movies/1.xml
  def show
    @movie = Movie.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @movie }
    end
  end

  # GET /movies/new
  # GET /movies/new.xml
  def new
    @movie = Movie.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @movie }
    end
  end

  # GET /movies/1/edit
  def edit
    @movie = Movie.find(params[:id])
  end

  # POST /movies
  # POST /movies.xml
  def create
    @movie = Movie.new(params[:movie])

    respond_to do |format|
      if @movie.save
        flash[:notice] = 'Movie was successfully created.'
        format.html { redirect_to(@movie) }
        format.xml  { render :xml => @movie, :status => :created, :location => @movie }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @movie.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /movies/1
  # PUT /movies/1.xml
  def update
    @movie = Movie.find(params[:id])

    respond_to do |format|
      if @movie.update_attributes(params[:movie])
        flash[:notice] = 'Movie was successfully updated.'
        format.html { redirect_to(@movie) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @movie.errors, :status => :unprocessable_entity }
      end
    end
  end

  # DELETE /movies/1
  # DELETE /movies/1.xml
  def destroy
    @movie = Movie.find(params[:id])
    @movie.destroy

    respond_to do |format|
      format.html { redirect_to(movies_url) }
      format.xml  { head :ok }
    end
  end
end

I’m new to rails so could you specify a little closer?

I am trying to change story partial to render edit link for all stories.

_story.html.erb

<% div_for(story) do %>
	<h3><%= link_to story.name, story %> <span id="edit_story"><%= link_to 'Edit', edit_story_path, :id=>story.id %></span></h3>
	<p>Submitted by: <%= story.user.login %> | Score: <%= story.votes_count %><br />Tags: <%= story.tag_list %></p>
<% end %>

(the “<%= link_to ‘Edit’, edit_story_path, :id=>story.id %>” part)

stories_controller.rb (excrept)

def edit
	@story=Story.find(params[:id])
end
def update
	@story=Story.find(params[:id])
	if @story.update_attributes(params[:story])
		redirect_to :action=>'show', :id=>@story
	else
		render :action=>'edit'
	end
end
def delete
	Story.find(params[:id]).destroy
	redirect_to stories_path
end

This is shovell application

The error currently is routing, since obviously I can’t think of a different solution because your examples have varying rails syntax

Error:
ActionController::RoutingError in Stories#index

Showing stories/_story.html.erb where line #2 raised:

edit_story_url failed to generate from {:action=>“edit”, :controller=>“stories”} - you may have ambiguous routes, or you may need to supply additional parameters for this route.

Your controller looks fine. As you already know this is a routing error of some sorts. One of the best things that you can do is to run “rake routes” from the command line and get a print out of all of your available routes.

This is where I think you are having a problem…

<%= link_to 'Edit', edit_story_path, :id=>story.id %>

It should probably look something like this.


<%= link_to 'Edit', edit_story_path(story) %>

Yeah, thanks! I stumbled over a helpful article that got me a solution.

For anyone who is trying to recreate this “tutorial” here is edit.html.erb contents

<%= error_messages_for 'story' %>

<h2>Edit this story! :D</h2>
<% form_for @story, :action=>'update' do |f| %>
<p>name:<br /><%= f.text_field :name %></p>
<p>link:<br /><%= f.text_field :link %></p>
<p>description:<br /><%= f.text_area :description %></p>
<p>tags:<br /><%= f.text_field :tag_list %></p>
<p><%= submit_tag 'Save changes' %></p>
<% end %>

I can’t explain the consequences of choosing “delete” instead of “destroy”, but you might want to change method name to “destroy” in the controller excerpt.

Now shovell application has edit functionality. Destroy should be easy to implement now.

Thanks!