user35288
user35288

Reputation:

Ruby on Rails: link updates DB

Simple RoR question...I am learning ROR and am making a simple voting app. The candidates are listed in a table and have upvote/downvote links next to their name. I am trying to make it so all the user does is click the link, the vote count is updated, and they are redirected to the initial page. I am not using scaffolding. For some reason this action is not doing anything close to what I want:

def upvote
  @name = Name.find(params[:id])
  @name[:votes] += 1
  respond_to do |format|
    if @name.update_attributes(params[:name])
      flash[:notice] = 'Candidate was upvoted'
      format.html = { redirect_to :action => "index" }
      format.xml = { head :ok }
    else
      format.html = { render :action => "index" }
      format.xml = { render :xml => @name.errors, :status => :unprocessable_entity }
    end
  end
end

I do have the link in the view calling the correct action, it's trying to call :show, though.

please don't judge me too harshly lol...

Upvotes: 1

Views: 201

Answers (2)

Schrockwell
Schrockwell

Reputation: 838

The update_attributes method is generally used to set the fields of an ActiveRecord object from a form POST. The fields would be found as the hash params[:name], e.g. params[:name][:votes].

If you are clicking on a link to call the upvote method, then you are just doing a GET request. All you need to do is call @name.save to save the record.

def upvote
  @name = Name.find(params[:id])
  @name[:votes] += 1
  respond_to do |format|
    if @name.save
      flash[:notice] = 'Candidate was upvoted'
      format.html = { redirect_to :action => "index" }
      format.xml = { head :ok }
    else
      format.html = { render :action => "index" }
      format.xml = { render :xml => @name.errors, :status => :unprocessable_entity }
    end
  end
end

EDIT: From the comments, we also determined that the routes were set up improperly and that the link_to code in the view needed to include @name.id.

Upvotes: 4

Steve
Steve

Reputation: 73

Typically the RESTful URL that maps to show is:

my_resource/id

So, e.g.,

candidates/1

Just at a guess, I'll bet if you look in config/routes.rb, you'll find something like:

map.resources :candidates

Where my_resource is the name of your controller. If you are going to use this kind of routing, then how does the resource provide upvoting? The custom method seems wise in this case, so:

map.resources :candidates, :collection => { :upvote => :post }

If you run

rake routes | grep candidate

before and after, you can see what's been added. Hope this helps.

Upvotes: 2

Related Questions