I'm testing a rails controller and attempting to perform a get with the code:
delete :remove_logs, :id => 3
And it consistently returns me an ActionView::MissingTemplate exception. I know that this is because there is no view associated with the get. There is a route for this method (from rake routes):
remove_logs /devices/remove_logs/:id(.:format) {:controller=>"devices", :action=>"remove_logs"}
The function itself works perfectly for the actually webpage as it's being called with:
<%= link_to "Remove History", remove_logs_path(device),
:class => "medium red button", :confirm => 'This will remove all history from
this device. Are you sure?', :method => :delete %>
So my question is, is there a way to bypass or trick the test to not attempt to access the view and just access the controller method? This isn't my system I'm testing so I really don't want to make a new blank view or anything similar.
I think the problem may be related with the code in controller (remove_logs action) which usually has some code about redirecting to another url like bellow:
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :action => :index
end
I test with Test::Unit in my rails app, and it goes fine when having redirecting code.
Related
I this view is currently in the views/projects/show.html.erb file however I want it to use the website controller for deleting this file:
<%= link_to 'Delete', #website, :controller => 'website', :action => 'delete', method: :delete, data: {confirm: "Are you sure you want to delete this asset?"}%>
It returns the error 'Could not find action destroy in the ProjectsController'. Also i don't have #website defined in the projects controller so should I be using something else? Or am I still able to access it because it is defined in the websites controller.
#controllers/websites_controller.rb
class WebsitesController < ApplicationController
def new
#project = Project.find(params[:project_id])
#website = #project.assets.build(:type => 'Website', :project_id => Project.find(params[:project_id]), :asset_number => #project.assets.size + 1)
end
def create
#website = current_user.assets.build(website_params)
#website.update_attributes(:project_id => #project)
if #website.save
flash[:notice] = "Asset successfully added."
redirect_to(:controller => 'projects', :action => 'show', :id => #website.project_id)
else
render(:action => 'new')
end
end
def delete
#website = Asset.find(params[:id])
end
def destroy
asset = Asset.find(params[:id]).destroy
flash[:notice] = "The asset '#{asset.title}' has been destroyed Successfully."
redirect_to(:controller => 'projects', :action => 'index')
end
private
def website_params
params.require(:website).permit(:id, :project_id, :asset_number, :title, :type, :url, :page_rank, :rev_company ,:social_pages)
end
end
If you are using this link on the show page for projects then #website will not be available unless it is defined in the projects controller.
That said, if there is some relationship between the project and the website, you could use that as opposed to defining #website in your projects controller.
Also, as far as your link_to is concerned, I do not believe that you can specify controller and action in the link_to like that. Instead, you should use the path to #website. Which should make your link_to look something more like this:
<%= link_to "Delete", website_path(#website), method: :delete, data: {confirm: "Are you sure you want to delete this asset?" %>
However, the model that your websites_controller appears to handle is actually an Asset. Without seeing your routes it is hard to guess how you have set them up, but assuming that you do something like
map.resources :assets, :controller => 'websites'
in your routes. Then in your link_to instead of using website_path(#website) you would likely use asset_path(#website).
Generally speaking, it is rarely a good idea to defy rails convention by naming things inconsistently from your model in ruby. If your Asset model uses single table inheritance or you are implying something like single table inheritance and are using controllers to separate responsibilities, then this may perhaps be an exception, but you will still need to be careful to ensure you are mapping to the correct place in your routes.
You may want to read up on the rails guide for routing, as it is a very good resource and explains pretty well how destroy gets mapped, which in turn explains why the link_to for it looks the way that it does.
#website available in the show action is the the one defined in the projects controller because it is he one rendering the current html page.
Therefore the one you wish to delete is not available at the moment.
So I'm currently trying to map my building's network with a RoR implementation. I have a good floor plan set up, and I've created the switch objects for it as well. Eventually, the switches will have many jacks, and each jack will map one-to-one with a room number.
Currently everything is working perfectly through the floors and switches until I try to show the switch individually. I'm trying to do this by using the show method in a separate controller. Originally the floor controller was in charge, but now I want the switch controller to be.
Here is my partial switch code (apps/views/switch/_switch.html.erb):
<p>
<%= switch.title %>
<%= link_to 'show', :controller => "switches", :action => 'show' %>
<%= link_to 'Destroy', [switch.floor, switch],
:confirm => 'Are you sure?',
:method => :delete %>
</p>
Here is my show method (apps/controllers/switches_controller.rb):
...
def show
#floor = Floor.find(params[:floor_id])
#switch = #floor.switches.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #switch }
end
end
...
When I do not tag the switch controller in the partial, whenever I click show the link acts as a link back to the same page...basically just a refresh. When I do tag the switch controller I get the ' No route matches [GET] "/assets" ' error.
I've tried MULTIPLE different syntaxes and nothing has worked. If anyone can help me out I will be very thankful!!
Please let me know if it's necessary to post more of my code and I will.
You can run 'rake routes' command to list all available routing options and recommend you to use url/path rather than specifying controller and actions for individual links.
I assume that you have setup nested route for floor and switch, then to obtain this URL i.e
/floors/:floor_id/switches/:id/show
you can use
<%= link_to "Switch", floor_switch_path(switch.floor, switch) %>
'Show' method used to display particular element. Particular switch in your case. So you need to send :id to your controller, like this
link_to "Switch", :controller => "switches", :action => "show", :id => switch
I'm trying to do something very simple in my first Rails app (Rails 3) and I'm not sure what I'm doing wrong, or if there's a better approach. Can't find anything on the web or here that has solved it for me despite much searching.
In the app I have WorkRequests and Articles. When viewing an Article, I want a button to create a WorkRequest and, when the new WorkRequest form appears, have the article filled in. Essentially, I'm trying to pass the Article.id to the new WorkRequest.
Works in link_to just by adding the parameter, but I want it to be a button. While it shows up in the Article form's HTML as a query parameter, it never gets to the WorkRequest.new method. This article from 2010 explains the problem in some detail, but the solution does not work for me (see my comment at the end of the page.)
This seems like it should be a fairly easy and common thing to do (once I figure it out, there are several other places in my own app where I want to do the same thing) but I've been banging my head against this particular wall for a few days now. I am new to Rails--this is my first app--so I hope someone more experienced can help!
Thanks in advance.
Just circling back to finish this up. Ultimately I solved this by using link_to but using jQuery to make it look like a button. #kishie, if you're saying you made this work with button_to I'd like to see the code, but as I like jQuery it's solved as far as I'm concerned (for this app, anyway.)
Here's the code in Article#show view. (The class is what makes it look like a button via jQuery.)
<%= link_to "New Request", new_work_request_path(:article_id => #article.id), :class => "ui-button" %>
Here's the code in Work_Request controller's new method:
if !params[:article_id].blank?
#work_request.article = Article.find(params[:article_id])
end
Then the Work_Request#new view renders it properly.
Add this line of code in your routes.rb file.
resources :work_requests do
member do
post 'new'
end
end
It shouldn't be the GET method because you're sending information to the server, via :module_id. This will then work.
<%= button_to("Add WorkRequest", {:controller => "work_request", :action => "new", :article_id => #article.id})%>
I just hit a similar issue and I got it to work by passing the parameter as follows:
<%= button_to("Add WorkRequest", new_work_request_path(:article_id => #article.id), :action => "new", :method => :get)%>
In article#show
<%= button_to("Add WorkRequest", {:controller => "work_request", :action => "new", :article_id => #article.id})%>
In work_requests#new
<%= f.text_field :article_id, :value => params[:article_id]%>
If you nest your resources for :work_requests within :articles in your routes.rb, then pass your params[:id] which would be your article_id and add :method => :get to the button_to call, you should be okay.
# config/routes.rb
resources :articles do
resources :work_requests
end
# app/views/articles/show.html.erb
<%= button_to "Add Work Request", new_article_work_request_path(params[:id]),
:method => :get %>
# app/controllers/work_requests_controller.rb
class WorkRequestsController < ApplicationController
...
def new
#work_item = WorkItem.new
#article = Article.find(params[:article_id])
...
end
...
end
I'm trying to implement the "Friendship" in my Rails 3 app as described in Railscast 163:Self Referential Assosication
I have everything set up as described. I am using a basic user model that logis in with Authlogic which works fine. However when I try to add a friend using the following link:
<% for user in #users %>
<%=h user.username %>
<%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post %>
<% end %>
I get a redirect to http://localhost:3000/friendships?friend_id=2 and a Unknown action The action 'index' could not be found for FriendshipsController error with no further explanation. This is expecially strange since I have a hard coded redirect back to the "User#show" method for my current user (i.e. redirect back to profile after adding friend).
If it helps, here is my "friendships#create" method:
def create
#friendship = current_user.friendships.build(:friend_id => params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to :controller => 'users', :action => 'show', :id =>'current_user'
else
flash[:notice] = "Unable to add friend."
redirect_to :controller => 'users', :action => 'show', :id =>'current_user'
end
end
Any idea what could be causing this? I found someone having a similar problem here but I couldn't find a definite fix: Rails 3 and Friendship Models
Thanks in advance for your help!
~Dan
I think that link_to put the arguments into the query string as it is creating with html link even if you put :method => :post if js is disabled.
you could simulte a post with javascript :onclik event.
aniway , use a link_to with method :post is generaly a bad idea.
in rails you could use button_to helper for this pourpose and style it like a link.
edit:
In Rails3 doc seems that link_to have to simulate the same behaviur of button_to when called with params :method=>:post
(dynamically create an HTML form and
immediately submit the form ).
but it's not true for me in Rails 3.0.3 even if javascript is enabled.
I will investigate.
anyway you should be using buttons and forms for anything that isn't a GET; hyperlinks intentionally don't allow for methods other than GET
edit2:
ok,
rails3 don't create a inline form for simulate the post request via link. in Rails3 a data-method=post attribute is added to the tag for manipulate it via javascript function. this way the request gracefully degradate in a get call if js is disabled.
It's a late answer but it's a solution to this problem (at least it works for me):
<%= link_to "Add Friend", {:controller => :friendships, :action => :create, :friend_id => user_id }, :method => :post %>
I know it's long overdue for your problem, but it may help someone :)
I am trying to convert my Rails 2 app to Rails 3, but I can't delete any resources using my old Rails 2 code. To be precise I am trying to delete a resource, using this link:
<%= link_to image_tag("misc/delete.png"), #book, :confirm => 'Are you sure?', :method => :delete %>
And yet it doesn't work at all! It just behaves as if the :confirm option and :method option haven't been set at all, i.e. redirects me to the url of the #book object without even showing an alert box.
The generated HTML in Rails 3 is:
<img alt="Delete" src="/images/misc/delete.png?1205252772">
The generated HTML in Rails 2 was:
<img alt="Delete" src="/images/misc/delete.png?1279402305">
It's an obvious difference, but I've got no idea how I should handle this problem.
My controller looks like so:
class BooksController < ApplicationController
before_filter :require_admin, :only => ['new', 'create', 'edit', 'update', 'destroy']
# ....
def destroy
puts "-------------- DESTROYING BOOK --------------"
#book = Book.find(params[:id])
#book.destroy
flash[:notice] = "Successfully destroyed book."
session[:restore] = request.referer
redirect_to back(edit_author_url(#book.author))
end
end
And the string "destroying book" doesn't show on the console, so I think there surely must be something wrong.
Has something in the restful handling been changed in Rails 3 that I should get to know of?
Thanks, guys!
You need add the rails javascript library.
To jQuery : http://github.com/rails/jquery-ujs
To Prototype : http://github.com/rails/prototype-ujs