Ruby on Rails link_to :method => :delete syntax - ruby-on-rails

This is a nub question. I have a resource Project which has_many Feeds. When I am viewing the list of nested Feeds on the Project page, I have a Delete button to remove that Feed from the Project. It works with this syntax:
<%= link_to 'Delete', [feed.project, feed], :confirm => 'Are you sure?', :method => :delete %>
But that then directs to the page listing all the Feeds, and I instead want it to redirect back to the Project page the user was just at. Is it a matter of changing [feed.project, feed] or is it something else? I don't quite understand the syntax of link_to well enough yet.
EDIT:
In my feeds_controller.rb, I changed the redirect line to :back
def destroy
project = Project.find(params[:project_id])
#feed = project.feeds.find(params[:id])
#feed.destroy
redirect_to :back
respond_to do |format|
format.html { redirect_to :back }
format.xml { head :ok }
end
end

You must have a look at the controller for this resource. It should be somewhere like app/controllers/projects_controller, where's there should be an action named destroy. The code that do the redirect must be in there. You'll have to change the following line:
redirect_to project_feeds_url(project)
to this
redirect_to :back

in your controller
def destroy
#project = Project.find(params[:project_id])
#feed = #project.feeds.find(params[:id])
#feed.destroy
redirect_to #project
end

Related

Delete method returning error after devise logout

I'm running into a problem that I'm not exactly sure how to fix.
I have a simple to do list application with AJAX functionality on methods such as 'new', 'create', 'complete', 'delete', as well as Devise authentication.
When I first enter a new session with a User, all of these methods work without a problem. Additionally, the tasks are saved to only the user account, which is perfect.
However, when I log out of an account, and then log back in, the delete method no longer works. I receive the following error:
ActiveRecord::RecordNotFound (Couldn't find Task with 'id'=)
My tasks_controller.rb is below:
class TasksController < ApplicationController
def index
#task = current_user.tasks.all
end
def new
#task = Task.new
respond_to do |format|
format.js
format.html
end
end
def create
#task = current_user.tasks.new(task_params)
#task.save
respond_to do |format|
format.html
format.js
end
end
def update
#task = current_user.tasks.find(params[:id])
#task.toggle :complete
#task.save
respond_to do |format|
format.html
format.js
end
end
def destroy
#task = Task.find(params[:id])
#task.destroy
respond_to do |format|
format.js
format.html
end
end
private
def task_params
params.require(:task).permit(:id, :title, :complete)
end
end
I'm not exactly sure how to fix this problem. Would anyone have an idea on what is going wrong here?
EDIT:
I noticed that on my index page, I have a link to destroy the user's session at the top:
<%= link_to "Log Out", destroy_user_session_path, :method => :delete %>
I'm wondering if rails is having some trouble with this as both the logout link and the delete link are referencing the same method. If so, how can I change the name of the delete method for Task?
<div class="delete"><%= link_to "X", task_path(#task), method: :delete, remote: true %></div>
What is #task referencing? It looks to me like you've set #task to a collection #task = current_user.tasks.all.
Which would be why your delete method can't find a specific record to delete.
-EDIT-
Change #task in your index controller to #tasks as it is a collection.
In your view, do something like:
<% #tasks.each do |task| %>
<div><%= task.title %><div class="delete"><%= link_to "X", task_path(task), method: :delete, remote: true %></div></div>
<% end %>
The key here is that you have task_path(task) which is referencing a specific task id as opposed to task_path(#task) which is referencing a collection of tasks.

Keeping validation errors after redirect from partial back to the same page that has the partial

So I'm trying to get the errors from my form that is rendered as a partial inside my root_path. After I attempt to post it, and it fails (or succeeds), I want to redirect back to the root_path. However, redirect_to decides to not save any information for the validation.
Wondering how to do this.
class PostsController < ApplicationController
def new
#post = Post.new
end
def create
#nom = current_user.noms.build(params[:nom])
if #nom.save
flash[:success] = "Nom created!"
redirect_to root_path
else
flash[:error] = #nom.errors
redirect_to root_path
end
In my Home/Index, I render the partial for the form of the post.
= form_for [current_user, #post] do |f|
= f.text_field :name
= f.select :category
= f.text_area :description
= f.submit "Post", class: "btn btn-primary"
- #post.errors.full_messages.each do |msg|
%p
= msg
It should be keeping the errors at the bottom of the form after it redirects to the root_path.
I'd also like to keep the information that was there after the validation failed.
You should not use redirect in this case, instead use render:
class PostsController < ApplicationController
#..
def create
#nom = current_user.noms.build(params[:nom])
if #nom.save
flash[:success] = "Nom created!"
redirect_to root_path
else
flash[:error] = #nom.errors
render :template => "controller/index"
end
end
Replace controller/index with names of you controller and action
Also check this question
This seemed to work for me
format.html { redirect_to :back, flash: {:errors => "Document "+#requested_doc.errors.messages[:document][0] }}
I don't know if this could cause any other exception issues.
You can not use redirect_to for showing the error messages of an object because while redirecting it discards your object which does have linked with the error_messages & took a new object to redirect the path.
So in that case, you only have to use render.
respond_to do |format|
format.html {
flash[:error] = #account.errors.full_messages.join(', ')
render "edit", :id => #account._id, sid: #account.site._id
}
end

rails simple ajax request

i have a problem with ajax request:
in my app i am trying to configure a simple rank system, and i set it up, but whan i click on rank button - i reload the page and rank is refreshed.
Help my realize that in ajax:
i done that:
in posts/show.html.erb i have that:
<div id='vote_update'>
<%= render 'vote/update' %>
</div>
in vote/_update.html.erb i have :
<% if can? :update, Vote %>
<%= form_for([#post, #post.vote], remote: true) do |f| %>
...
<%= f.submit "vote" %>
in vote/update.js.erb i have:
$('#vote_update').html("<%= j render('vote/update') %>");
and in vote_controller.rb i have:
def update
post = Post.find(params[:post_id])
vote = post.vote
...
respond_to do |format|
if vote.save
format.html {
redirect_to post_path(post),
:notice => "You vote counted!"
}
format.js
end
end
end
if i remove romete: true - everything goes right ( page is reload, i saw (:notice) "You vote counted!" and rating is updated, but if i put remote: true back, i saw nothing ( some mistakes in firebug console ) - but when i reload page - ratign is updated, nd i saw norml result - i think i madesome mistakes in redirecting or i dont know
help please
your ajax code will come in format.js block. where you can update the html where you are showing the rank.
change
respond_to do |format|
if vote.save
format.html {
redirect_to post_path(post),
:notice => "You vote counted!"
}
format.js
end
end
to
if vote.save
respond_to do |format|
format.html {
redirect_to post_path(post),
:notice => "You vote counted!"
}
format.js
end
end
Not sure though

Why Destroy Action is NOT being fired?

I am using Rails 3 and trying to see why the Destroy action is not being fired! My html fired is defined as follows:
<%= link_to "Delete", :action => "destroy", :id => article, :method => :delete, :confirm => "are u sure?" %>
And here is the ArticlesController:
def destroy
#article = Article.find(params[:id])
#article.destroy
respond_to do |format|
format.html { redirect_to articles_url }
end
end
When I click on the "Delete" link it takes me to the show action. I am not sure why is that?
Your link_to should be this:
<%= link_to "Delete", #article, :method => :delete, :confirm => "are u sure?" %>
This will generate the correct URL for your article and go to the destroy action.
Have you deleted the javascripts directory which resides in the public directory of your rails app?
If yes, create a new rails project and copy the javascripts directory in your actual project
Make sure your application.js has included this line:
//= require jquery_ujs
That solved my issue.
That first line should be
#article = Article.find(params[:id])
Once you make this change, you won't be able to redirect to #article, since it will be gone; you'll probably need to replace that last line with redirect_to articles_url. The whole new method will be:
def destroy
#article = Article.find(params[:id])
#article.destroy
respond_to do |format|
format.html { redirect_to articles_url}
end
end
If you have trouble with stuff like this, try creating a scaffolded model with rails generate scaffold Test to see what the default options are.
It could also be this Why are default javascript files required to create a destroy link in rails?.

link_to :action => 'create' going to index rather than 'create'

I am building a fairly simple recipe app to learn RoR, and I am attempting to allow a user to save a recipe by clicking a link rather than through a form, so I am connecting the user_recipe controllers 'create' function through a link_to.
Unfortunately, for some reason the link_to is calling the index function rather than the create.
I've written the link_to as
<%= "save this recipe", :action => 'create', :recipe_id => #recipe %>
this link is on the user_recipes/index.html.erb and is calling the 'create' function of the same controller. It doesn't seem to make a difference if I include the :controller or not.
The controllers look like this
def index
#recipe = params[:recipe_id]
#user_recipes = UserRecipes.all # change to find when more than one user in db
respond_to do |format|
format.html #index.html.erb
format.xml { render :xml => #recipes }
end
end
def create
#user_recipe = UserRecipe.new
#user_recipe.recipe_id = params[:recipe_id]
#user_recipe.user_id = current_user
respond_to do |format|
if #menu_recipe.save
format.html { redirect_to(r, :notice => 'Menu was successfully created.') }
format.xml { render :xml => #menu, :status => :created, :location => #menu }
else
format.html { render :action => "new" }
format.xml { render :xml => #menu.errors, :status => :unprocessable_entity }
end
end
In the standard REST scheme the index action and the create action both have the same url (/recipes) and only differ in that index is accessed using GET and create is accessed using POST. So link_to :action => :create will simply generate a link to /recipes which will cause the browser to perform a GET request for /recipes when clicked and thus invoke the index action.
To invoke the create action use link_to {:action => :create}, :method => :post, telling link_to explicitly that you want a post request, or use a form with a submit button rather than a link.
Assuming you have default resources set up in your routes file, i.e. something like this
resources :recipes
The following will generate a link that will create a recipe; i.e. will be routed to the create action.
<%= link_to "Create Recipe", recipes_path, :method => :post %>
For this to work, JS needs to be enabled in your browser.
The following will generate a link that will show all recipes; i.e. will be routed to the index action.
<%= link_to "All Recipes", recipes_path %>
This assumes the default which is a Get HTTP request.

Resources