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...
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.
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.
Related
I am running rails 3.2
I have created a nested form (requests > tags) with coffeescript handling the addition of new tags.
Everything works with the exception of the form posting a blank tag.name
I am trying to write a method to delete the blank field before the form posts. I realize this may be the wrong approach, but I am still a beginner:
requests_controller.rb
def create
#request = current_user.requests.build(params[:request])
#tag = Tag.new
if #tag.name.blank?
destroy_blank
end
respond_to do |format|
if #request.save
format.html { redirect_to(#request,
:notice => 'Request was successfully created.') }
format.json { render :json => #request,
:status => :created, :location => #request }
else
format.html { render :action => "new" }
format.json { render :json => #request.errors,
:status => :unprocessable_entity }
end
end
end
request.rb
def destroy_blank
blank = #tag.name
blank.delete
end
I hope that's clear. If not let me know and I will include more information.
If you can't stop blank tags from coming in, you can create a before_create filter in the model to skip saving blank tags. Leave the controller clean and simple.
Good luck!
I have a Rails 3.0 application which features a simple voting mechanism that adds a count to a number of down votes. I've set up a PUT route in routes.rb and created a method in my controller to handle it. The down vote link itself renders properly, but on clicking it gives me a Routing Error No route matches "/venues/18/down_vote" error.
Here's my controller code:
def down_vote
#venue = Venue.find(params[:id])
respond_to do |format|
if #venue.update_attribute(:mon_closed_accuracy_downvotes => #venue.mon_closed_accuracy_downvotes + 1)
format.html { redirect_to(:back, :flash => { :success => "Shenanigans were successfully called on #{ #venue.name }'s closing time." }) }
format.xml { head :ok }
else
format.html { render :action => 'show' }
format.xml { render :xml => #venue.errors, :status => :unprocessable_entity }
end
end
end
Here's my route code for the down_vote route:
resources :venues do
put 'down_vote', :on => :member
end
View code (inside a partial for a list of venues):
<%= link_to 'Incorrect?', down_vote_venue_path(venue), :method => :put %>
Again, the view itself renders fine, and the link renders as expected:
Incorrect?
Any ideas?
Sounds like you've got a problem with your javascript. Are you including the proper files? What does your layout look like?
please can somebody help me with this .i want to create a renew link which will update some of the fields in a table called members,am using rails 3 and i have created my action and the corresponding view but i still have an error that states
"undefined method'renew_member_path' for #<#:0xb66bcae0>"
below is the action i created in the members_controller
Class MembersController
def renew
#member = Member.find(params[:id])
respond_to do |format|
if #member.renew_attributes(params[:member])
format.html { redirect_to(#member, :notice => 'Member was succesfully Renewed.'}
format.xml {head :ok }
else
format.html { render :action => 'renew'}
format.xml { render :xml => #member.errors, :status => :unprocessable_entity}
end
end
end
I created a view called renew.html.erb
Your route is not set. You need to update your routes.rb file to something like this:
match 'members/renew' => 'members#renew', :as => :renew_member
I try to do following:
A user is on his profile page. Now he edits his profile. He klicks on update and the data is saved.
Now I want to redirect the user to another kind of profile-edit-page.
I did the following in my users_controller.rb:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.'
if(#user.team_id != nil)
format.html { redirect_to(#user) }
else
format.html { redirect_to choose_team_path }
end
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def choose_team
#user = User.find(params[:id])
end
I created a view: /users/choose_team.html.erb
Now I get the following error:
undefined local variable or method `choose_team_path' for #<UsersController:0x1f56650>
So I added choose_team to my routes.rb:
map.choose_team 'choose-team', :controller => 'users', :action => 'choose_team'
Now, after submitting my first edit form, it redirects me to http://localhost:3000/choose-team
and I get following error: Couldn't find User without an ID
What I want:
If a user has no team_id, he should be redirected to my choose_team.html.erb for choosing a team, else he should be redirected to his profile/show.
How to do this?
EDIT:
By writing format.html { redirect_to :action => "choose_team" } instead of format.html { redirect_to choose_team_path } it is working. But how can I get an url like /users/1/choose_team ? At the moment it is just /choose_team .
You have to add your action like this:
map.resources :users, :member=>{:choose-team=>:get}
Because, if you have an action like index, which returns a collection of users than should be put in collection hash. If your action is specific to a user you have to add to the :member hash, now you will get an url like /users/1/choose_team
You need put this route before your map.resources :users first in first choose with route.rb
Add following line in route.rb and restatrt your server
map.resources :users, :collection=>{:choose-team=>:get}
the line
format.html { redirect_to choose_team_path }
isn't passing an id to choose_team_path.
Your choose_team action uses the :id param but one isn't being supplied. This is why you get the Couldn't find User without an ID error.
I have an action in my PostsController named 'tagged', which I want to return all posts tagged with whatever term.
In my routes.rb I have the following (at the top):
map.connect 'posts/tagged/:tag', { :controller => 'posts', :action => 'tagged', :tag => /[a-z\-]+/ }
Yet navigating to posts/tagged/yes returns a RecordNotFound error:
Couldn't find Post without an ID
In my tagged.html.erb file, I'll eventually be using the find_tagged_with method from acts_as_taggable_on_steroids, but for now I've put a simple Post.find(:all) to eliminate the possibility of error.
It seems like my map.connect is being overridden, and the same error occurs even if I comment the whole of the routes.rb file out except my new line.
Ok, because you can comment out the default routes that means your problem is not in your routes at all. It's that your tagged action in the posts controller probably has something like this.
def tagged
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
Or perhaps if you spent a little more time it looks like this:
def tagged
#post = Post.find(params[:tagged])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
Where as what you want is this:
def tagged
#post = Post.find(:all, :conditions => {:tagged => params[:tagged]})
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
Anyway, you should be writing functional tests for this stuff and not testing in the browser.
Why not add a RESTful route for the "tagged" action?
map.resources :posts, :member => { :tagged => :put }