Reputation:
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
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
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