Using a controller action on a button click - Rails - ruby-on-rails

Really new to using Ruby on Rails and programming in gentle so apologies in advance if this seems very basic.
I'm working on a very simple wiki based website, where users can upgrade and downgrade their account.
In my downgrade.html.erb I have the following code:
<p>Are you sure you want to downgrade back to standard?<p>
<%= link_to "Yes", :controller => :charges, :action => :downgrade1, class: 'btn btn-danger' %>
<%= link_to "No", root_url, class: 'btn btn-success' %>
and in my charges_controller.rb I have my downgrade1 method:
def downgrade1
if current_user.premium?
current_user.update_attribute(:role, 'standard')
flash[:success] = "You have been downgraded to standard."
redirect_to root_url
else
false
end
end
Ultimately, when the user clicks that 'Yes' button, I want that downgrade1 method to run and the user's account to be downgraded back to standard.
However, what happens is the website loads a 'show webpage' with my header and footer, but the user is still a premium user.
Any ideas how I can fix this?

Thanks for your attempts to solve my problem, both your answers eventually led to me finding the solution.
In the end, I used this code in my view:
<%= button_to "Yes", { :controller => "charges", :action => "downgrade1"}, class: 'btn btn-danger' %>
and added this to my routes.rb
post "charges/downgrade1" => "charges#downgrade1"
Downgrading now works as planned.
Thanks again for your help.

I think the problem here is that you didn't specify the HTTP method for your link_to, like
<%= link_to "Yes", :controller => :charges, :action => :downgrade1, class: 'btn btn-danger', :method => :patch %>
By default, it will call a GET method, then nothing in your database will be changed.
And make sure you have defined that method in your routes.rb

You are missing one closing tag at the end of your if - else statement:
else
false
end
end

Related

Rails routes confuses a custom destroy method with destroy method in users controller

I have a users controller with the following two destroy methods:-
def destroy
#user = User.find_by(params[:id])
#user.destroy
flash[:success] = "Account successfully closed"
redirect_to root_path
end
def destroy_avatar
#user = User.find_by(params[:id])
#user.remove_avatar!
#user.save
render 'edit'
end
The first is the default destroy method that deletes the user. The second is one that I defined to let the user delete their avatar from their user edit page.
I had the following defined in the routes.rb to get the destroy_avatar working:-
delete '/users/:id', to: 'users#destroy_avatar', as: 'destroy_avatar'
resources :users
But unfortunately when I implemented this the close account button I had on the user edit page reverted to the destroy_avatar action.
This is the call to both the actions from the view:-
.
.
.
<% if current_user.avatar_url %>
<%= link_to "Delete avatar", destroy_avatar_path,
method: :delete,
data: {:confirm => 'Are you sure?'},
class: 'btn btn-xs btn-danger',
"data-toggle" => "tooltip",
"data-placement" => "right",
"title" => "Delete avatar" %>
.
.
.
<%= link_to "Close account", user_path(#user),
method: :delete,
data: {:confirm => "Are you sure?"},
class: "btn btn-xs btn-danger"%>
.
.
.
I went looking to see if there is a way to get the destroy_avatar to work without using routes, but I found a way to do it with AJAX without requiring an additional route, which would actually be more convenient but I don't know Javascript and couldn't customize the code to my case.
I am still learning rails and I don't know what I don't know! So I would like to know what options I have.
Is there a way to do this without using two routes? If no, how should I customize the route for the destroy_avatar so that there is no conflict with the route for user destroy action?
Ok, I figured it out.
Changed the route to
delete '/users/:id/destroy_avatar', to: 'users#destroy_avatar', as: 'destroy_avatar'
and from the view:
<%= link_to "Delete avatar", "/users/#{#user.id}/destroy_avatar" %>

Routing Error rails

At this time I added a new route in config/routes.rb this way
resources :users do
get "newasignacion" => "users#newasignacion", :as => "newasignacion"
end
And the link is this way
= link_to "Asignar Tarea", user_newasignacion_path(#user),
:class => 'btn btn-success btn-mini' %>
But when I access the link i get this link:
http://localhost:3003/users/%23%3CActiveRecord::Relation::ActiveRecord_Relation_User:0xa6c7f3c%3E/newasignacion
Can somebody tellme why is this problem ?
It should be like that http://localhost:3003/users/5/newasignacion.
Whatever is assigned to #user is an class type ActiveRecord::Relation, when it should be an instance of User. For the sake of illustration, see how passing User.first to your link helper outputs a valid link:
= link_to "Asignar Tarea", user_newasignacion_path(User.first),
:class => 'btn btn-success btn-mini' %>
Verify that you're correctly assigning a user to #user in whatever controller action is rendering out the view in question.

Rails destroy via Ajax thows js error

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'}

Add css class to rails link_to helper

I'm trying to style a rails link using css using the following code:
<%= link_to "Learn More", :controller => "menus", :action => "index", :class => "btn btn-inverse" %>
I would expect that this would create a link that looks like this:
Learn More
Instead, rails is rendering this -
Learn More
Has anyone else had this problem / know what I'm doing wrong? I know I can avoid this problem by manually creating the anchor tag rather than using helper, but I was wondering if there was a way to pass the css class info to the helper itself. I'm using Rails 3.2.6.
Thanks!
You have a syntax problem. Try this instead:
<%= link_to "Learn More", {controller: "menus", action: "index"}, class: "btn btn-inverse" %>
Some documentation for you to go further with the link_to Helper
They say:
Be careful when using the older argument style, as an extra literal hash is needed:
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"
# => Articles
Leaving the hash off gives the wrong link:
link_to "WRONG!", :controller => "articles", :id => "news", :class => "article"
# => WRONG!
I recommend you to use the URL helper generated following your routes configuration. In your case:
link_to "Learn More", menus_path, :class => "btn btn-inverse"
A little reminder on the Helpers generated:
# routes.rb
resources :users
# any view/controller
users_path #=> /users
edit_user_path(user) #=> /users/:id/edit
user_path(user) #=> /users/:id (show action)
new_user_path(user) #=> /users/new
Try new argument convention:
<%= link_to 'Learn More', 'menus#index', class: 'btn btn-inverse' %>
if you do not have a controller action / route necessary for the link, you can pass nil as the placeholder and get the classes to apply as necessary
<%= link_to 'link verbiage', nil, class: 'classes for action tag'%>
I solved my problem by the way
<%= link_to image_tag("imageexamplo.png", class: 'class or id examplo css'),{controller: "user" , action: "index"}%>
This is how i solved it using another view engine, HAML just in case a fellow developer is having this need
%i= link_to "Add New Blog Post", user_post_edit_new_url(current_user), :class => "fa fa-plus-circle"

Deleting from a namespace

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

Resources