This is probably a very simple question. I am new to Rails and have just hit my first major roadblock.
I have two controllers, Groups and MembershipRequests. When someone submits a MembershipRequest, the admin of the Group has the option to accept or deny the request. In my MembershipRequests controller, I have two methods: accept and deny. They both work, but now I'm unsure of dealing with my routes.
This is the relevant part of my routes.rb:
resources :groups do
member do
get 'members'
resources :membership_requests do
member do
post 'accept'
post 'deny'
end
end
...
end
end
Okay, onto my real question: I want to be able to accept and deny requests without an additional page. I want to use JavaScript to use a button on my MembershipRequests index page where the admin can accept or deny the requests.
Here's my erb code for the accept and deny buttons:
<%= link_to "Accept", :controller => 'membership_requests', :action => 'accept', :confirm => 'Are you sure?' %>
<%= link_to "Deny", :controller => 'membership_requests', :action => 'deny', :confirm => 'Are you sure?' %>
Clicking either of these links give me the
No route matches "/groups/1/membership_requests/1/{accept,deny}"
just like I would expect. But I do not know how to get around this. Thanks!
I think, link_to should also have :method => :post because you're mapping it to a custom (non-RESTful) action (that's just an assumption) and :remote => true, to tell rails that this link uses unobtrusive JS.
This screencast might help, or at least give a starting point.
Oh, and yes. As Ryan suggests, you'd better use something like this:
#requests.each do |request|
link_to "Accept", membership_request_accept_path(request), :confirm => 'Are you sure?', :remote => true
end
Related
Okay so I'm building a really simple list with items app, pretty much exactly the same as your standard to-do list application. I've managed to ajax-ify the creation of new 'points' within a list (point belongs_to :list and list has_many :points) but I'm having trouble with the 'destroy' action.
When I click on the destroy link in the browser, nothing visibly occurs, and I get the error Error: Syntax error, unrecognized expression: /lists/10/points/125 obviously with different values depending on the id of the list and point.
If I refresh the page or look at the db, it's clear that the entry has indeed been deleted. Without ajax, my destroy action works just fine. I feel like I must be missing something obvious, any ideas?
fyi the 'pro' attribute is just a boolean associated with every point.
points_controller.rb
def destroy
#point = #list.points.find(params[:id])
#point.destroy
respond_to do |format|
format.html { redirect_to list_url(#list) }
format.js
end
end
lists/show.html.erb
<% #list.points.each do |point| %>
<% if point.pro == true and point.valid? == true %>
<li class="weight-<%= point.weight %>"><%= point.content %>
<%= link_to "×".html_safe, [#list, point],
:remote => true,
:method => :delete,
:class=> "close",
:data => {:dismiss => 'alert'} %>
</li>
And it doesn't seem to matter what I put in views/points/destroy.js.erb, because the code doesn't seem to be getting executed.
Update
I figured it out, I had to change the path in the delete link to list_point_url(#list, point). The other problem was that my invalid javascript was causing a server error, so I didn't realize what the problem was (turns out #<%= dom_id(#point) %> needed to be wrapped in quotes).
Thanks all!
Maybe check if the delete link routes to the destroy controller action, because list_point_path doesn't really seem like a delete route.
Edit
Sorry for the lake of knowledge but I'm not sure what [#list, point] will produce as a route. This is what I have for a view of my own, just for your reference:
link_to "Delete", admin_photo_path(photo), :method => :delete, :confirm => "Delete this image?", :class => "btn-trash"
My admin_photo_path is a singular path that route to a single Photo instance; not a collection.
Edit
Simple way could be sending delete to the point object, maybe this could help?
link_to "×".html_safe, point,
:remote => true,
:method => :delete,
:class=> "close",
:data => {:dismiss => 'alert'}
I have setup a admin namespace in order to access models in the admin area: /admin/pages
However i have the following problem
i cant get the delete function to work under Admin::PageController for example or any of my models.
Does anyone know how to do this.
I have the following:
Admin::PageController I have the following
def destroy
#page = Page.find(params[:id])
#page.destroy
respond_to do |format|
format.html { redirect_to admin_pages_url }
format.json { head :ok }
end
end
Then on my page index file where i want a link to delete the record i have the following: (/admin/pages)
<%=link_to admin_page_path(page), :class => 'ico del' do %>
<%='Delete'%>
<% end %>
Does not seem to work. Anyone know how to get this to work?
you have missed :method option in link_to call
link_to 'Delete', admin_page_path, :confirm => 'Are you sure?', :method => :delete
or
<%=link_to admin_page_path(page), :class => 'ico del',:method => :delete do %>
<%='Delete'%>
<% end %>
The link_to helper defaults to a GET request unless you specify additional attributes to tell it how you want it to be handled.
In this case, you need to set some extra arguments:
<%=link_to "Delete", admin_page_path(page), :class => "ico del", :remote => true, :method => :delete %>
What actually happens in the background is the Rails UJS (unobtrusive javascript adapter) captures the click event and sends the request via AJAX. So you should see it hit your server with a POST (but it passes in _method => delete as well) to delete the object.
I'm also assuming you have your routes set up correctly. Something like:
namespace :admin do
resources :pages
end
I ask this question only because I'm curious.
The first line is standard, RESTful and of course invokes destroy method.
The second line returns a routing error.
The question is how to repair the second line to work like the first one. As I mentioned before, It's just for my curiosity and better ROR understanding.
<%= link_to 'delete', file, :method => :delete %></td>
<%= link_to 'delete', {:action => :destroy, :controller => 'files', :id => file.id.to_s}, :method => :delete %>
Bye
Disclaimer: I know this is not the way to do a delete. It is proof of concept on just how to access an action via a controller outside of REST.
You can do this:
<%= link_to 'delete', {:action => :destroy, :controller => 'files', :id => file.id} %>
You don't need the method destroy if you explicitly access the action. Also don't need the to_s for the file.id
We're adding a new method 'delete_stuff' to the WidgetsController of a scaffolded app.
in routes we added
match 'widget/delete_stuff/:id' => 'widgets#delete_stuff'
I CAN manually create html (GET) links like
My Custom Delete Stuff
But that's bad on so many levels (uses GET instead of DELETE, doesn't permit a CONFIRM dialog, isnt DRY, etc)
Problem is I can't figure out how to use the url helpers for a custom method... trying to do something like this:
<% link_to 'DeleteStuff', #widget, :confirm => 'Are you sure?', :method => :delete %>
But that just gets ignored when the html is rendered.
I'm clearly missing something fundamental on how to use link_to, any help will be appreciated!
Cheers,
JP
Looks like you're missing an equals sign at the beginning. It should read:
<%= link_to 'DeleteStuff', #widget, :confirm => 'Are you sure?', :method => :delete %>
to solve your routing and make your additional action a delete method try this;
in routes.rb
resources :widgets do
member do
delete 'delete_stuff'
end
end
First run rake routes to know what URL helpers are available to you. You may see a line beginning with:
delete_stuff_widget
You can then append path or url to get the name you should use in your views and controllers. I suspect your new link_to will look like:
link_to "DeleteStuff", delete_stuff_widget_path(#widget), :confirm => "Sure?", :method => :delete
First of all, I'm new at Ruby on Rails, so if there's a better practice than what I'm doing, please let me know.
What I'd like to do is to have multiple ajax submit buttons to perform different actions for a list of items with check boxes. So, when I select as many check boxes as I want, then I can choose what to do with them.
I could partially solve this using ajax as follows:
remote_form_for :profile, :url => {:controller => 'announcements', :action => 'deactivate'}, :html => { :method => :put} do |f|
f.submit 'Publish', :confirm => 'Are you sure?'
#Then the list
This works great. What I'd like to do now is to add another "submit" or button, so I can perform several actions, so I guess the :url statement at the remote_form_for will be replaced for something like that per each button. For example:
Publish button: perform some action in some controller.
Deactivate button: perform another action.
Mark as Read: perform another action.
Is it clear?
add as many "submits" as you like. All submits have the 'name' in the input tag set to 'commit' and the value set to the label. So you can check by looking in the params submitted:
remote_form_for :profile, :url => {:controller => 'announcements', :action => 'deactivate'}, :html => { :method => :put} do |f|
f.submit 'Publish', :confirm => 'Are you sure?'
f.submit 'Something Else"
# Then the list
in the controller
def deactivate
case params[:commit]
when 'Publish' then do something
when 'Something Else' then do something else
end
end
Finally, I could solve it by myself.
It's well known there's a bug for multiple submit buttons on ajax forms. I used the hidden workaround as explained here.
Thanks,
Brian