Ruby on Rails, Promote to Admin function - ruby-on-rails

I'm quite new to Ruby on Rails and I'm trying to learn a bit, so I tried making a new function.
The error I'm getting right now is:
ActionController::RoutingError (No route matches [POST] "/users/2"):
I'm trying to make a function to promote other users to admin, which is only possible as an admin.
My users_controller.rb contains:
def promote
if !User.find(params[:id]).admin?
User.find(params[:id]).toggle!(:admin)
flash[:success] = "User is promoted to admin."
redirect_to users_url
else
flash[:danger] = "Admins can't demote other admins."
redirect_to users_url
end
end
My _user.html.erb contains:
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
<% if !user.admin? %>
<br /> <%= link_to "Delete User", user, method: :delete,
data: { confirm: "You sure?" } %>
| <%= link_to "Promote to Admin", user, method: :promote,
data: { confirm: "You sure?" } %>
<% end %>
<% end %>
And then we have my routes.rb, which contains:
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get 'users/new'
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users do
member do
get :following, :followers
end
end
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
end
I can't exactly find what's going wrong. Some advice would be awesome!

def promote
#user = User.find(params[:id])
if #user.admin?
#user.toggle!(:admin)
flash[:success] = "User is promoted to admin."
redirect_to users_path
else
flash[:notice] = "Admins can't demote other admins."
redirect_to users_path
end
end
<%= link_to #user.name, #user %>
<% if current_user.admin? && !current_user?(#user) %>
<% if !#user.admin? %>
<br />
<%= link_to "Delete User", #user, method: :delete, data: { confirm: "You sure?" } %>
| <%= link_to "Promote to Admin", promote_users_path(user), method: :put, data: { confirm: "You sure?" } %>
<% end %>
<% end %>
in route
resources :users do
member do
get :following, :followers,
put :promote
end
end
or
match '/users', to: 'users#promote', via: :put

Related

ActionController::ParameterMissing in TagsController#create

I am attempting to trigger a destroy action from an index page for tags attached to multiple records. However, when the action is triggered I get the above error in the create action. The error does not occur when the create action is invoked. My code is as seen below.
Tag Controller
class TagsController < ApplicationController
before_action :require_user, only: [:edit, :update, :destroy]
before_action :set_search
def new
#tag = Tag.new
end
def create
tag = Tag.create(tag_params)
if tag.save
redirect_to tags_path
else
redirect_to sign_up_path
end
end
def destroy
#tag = Tag.find(params[:tag_id])
#tag.destroy
redirect_to tags_path
end
private
def tag_params
params.require(:tag).permit(:name)
end
end
Routes
Rails.application.routes.draw do
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
resources :recipes do
resources :ingredients, :steps
put :favorite, on: :member
end
resources :users
get 'recipes' => 'recipes#index'
get 'recipes/:id' => 'recipes#show'
get 'signup' => 'users#new'
get 'tags' => 'tags#index'
get 'new_tags' => 'tags#new'
post 'tags' => 'tags#create'
delete 'tags' => 'tags#destroy'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
root 'recipes#index'
end
Index
<%= link_to 'New Tag', new_tags_path(#tag) %>
<% Tag.find_each do |tag| %>
<%= tag.name %>
<%= link_to 'Delete Tag', #tag,
method: :destroy,
data: { confirm: 'Are you sure?' } %>
<% end %>
This route:
delete 'tags' => 'tags#destroy'
means "/tags" with no id parameter.
You have to tell the router that you want a part of the url used as the :tag_id
delete 'tags/:tag_id' => 'tags#destroy'
Anyway, I'd recommend you to stick with rails conventions and just use
resources :tags
and on the controller
#tag = Tag.find(params[:id])
I'm not sure why are you setting the routes manually, if you are new to Rails read this link: https://guides.rubyonrails.org/routing.html
You even have this lines
get 'recipes' => 'recipes#index'
get 'recipes/:id' => 'recipes#show'
which are unnecessary since resources :recipes already creates them.
The error stemmed from a combination of issues in the Link To statement in the view. The Link as it should be written is below...
<%= link_to 'Delete Tag', tag_path(tag),
method: :delete,
data: { confirm: 'Are you sure?' } %>

Delete subscription with a form Rails 4

I'm trying to have subscribers unsubscribe via a delete form where they enter their email and then submit and then delete the subscription. Not sure why this isn't working. I've tried a number of things via my controller. Would love some suggestions or alternatives.
Currently getting this error
Couldn't find Subscription without an ID
Subscriptions controller
def destroy
#subscriptions = Subscription.all
#subscription = #subscriptions.find(params[:id])
if #subscription.email == params[:email]
#subscription.destroy
flash[:notice] = "You have been unsubscribed"
redirect_to root_path
else
end
end
Routes
Rails.application.routes.draw do
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get 'users/new'
resources :posts
root 'static_pages#new_home'
resources :subscriptions, only: [:new, :create, :edit, :update, :show, :destroy]
get '/home' => 'static_pages#home'
get 'subscriptions' => 'subscriptions#show'
delete 'subscriptions' => 'subscriptions#destroy'
get '/about' => 'static_pages#about'
get '/author' => 'static_pages#author'
get '/contact' => 'static_pages#contact'
get '/book' => 'static_pages#book'
get '/signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :posts do
resources :comments
end
end
Unsubscribe partial in subscriptions view
<%= form_for #subscription, method: :delete do |f| %>
<div class="row">
<h2>Unsubscribe</h2>
</div>
<div class="row newsletter">
<form method="post" action="#" class="contact-form">
<div class="row email-label">
<%= f.label :email, :class => 'label-email' %>
<%= f.email_field :email %>
</div>
<div class="row">
<%= f.submit 'Unsubscribe', :class => 'btn-full-subscribe' %>
</div>
</form>
</center
<% end %>
I've tried a number of things with no luck. Help would be appreciated. Thanks. Subscriptions are not related to User model.
This line #subscription = #subscriptions.find(params[:email]) is causing the issue.
Try #subscription = #subscriptions.find_by_email(params[:email]) or better yet, use the id #subscription = #subscriptions.find(params[:id]).
ActiveRecord::find only uses ids: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find.
Problem is here
#subscription = #subscriptions.find(params[:email])
because find uses id to fetch the record if you want to fetch by any other field use find_by_"attribute_name", Replace it with
#subscription = Subscription.find_by_email(params[:email])
Or no need to write down extra code. No need to fetch all the subscriptions. To delete use
#subscription = Subscription.find_by_email(params[:email])
or
#subscription = Subscription.find(params[:id])
if #subscription.destroy
flash[:notice] = "You have been unsubscribed"
redirect_to root_path
end

Rails Routing Help - Edit/Show have :id/:action, but delete has :action/:id

my routes.rb
root 'pages#home'
get 'about', to: 'pages#about'
resources :articles
match ':controller(/:action(/:id))', :via => [:get, :post]
my articles_controller.rb
def delete
#article = Article.find(params[:id])
end
def destroy
article = Article.find(params[:id])
article.destroy
flash[:notice] = "Article destroyed successfully."
redirect_to(:action => 'index')
end
my delete.html.rb
<h2>Delete Article</h2>
<div class="subjects delete">
<h2>Delete Subject</h2>
<%= form_for(:article, :url => {:action => 'destroy', :id => #article.id}) do |f| %>
<p>Are you sure you want to permanently delete this subject?</p>
<p><%= #article.title %></p>
<div class="form-buttons">
<%= submit_tag("Delete Article") %>
</div>
<% end %>
</div>
Now the problem is when i click edit article its redirecting to
http://localhost:3000/articles/7/edit
Show is redirecting to localhost:3000/articles/7
Where as delete is redirecting to localhost:3000/articles/delete/8
and when clicking delete button it says The action '8' could not be found for ArticlesController
Why i dont get redirected to localhost:3000/articles/8/delete
i changed routes.rb to
match ':controller(/:id(/:action))', :via => [:get, :post]
in this delete works but edit doesnt.
You'll be best using the resources directive for the routes:
#config/routes.rb
resources :articles #-> url.com/articles/:id/destroy
resources :pages, only: [], path: "" do
get :about, on: :collection #-> url.com/about
end
root 'pages#home'
The above will provide the correct routes.
Your problem is you're submitting a form to try and change the value. This will not work; you'll need:
#app/views/articles/show.html.erb
<%= button_to "Delete", article, method: :delete, data: { confirm: "Are you sure?" } %>
This will call your posts#destroy controller & fire your code (which seems okay).

ActiveRecord::RecordNotFound in UsersController#deactivate (Couldn't find User with 'id'=)

With my rails app I can successfully destroy, sign up and log in users but I can seem to deactivate them. I get this error every time:
ActiveRecord::RecordNotFound in UsersController#deactivate (Couldn't find User with 'id'=)
record = s.execute([id], self, connection).first
unless record
raise RecordNotFound, "Couldn't find #{name} with '#{primary_key}'=#{id}"
end
record
rescue RangeError
Here's the User controller:
def deactivate
user = User.find(params[:user_id])
if current_user.admin?
user.deactivate_account!
redirect_to users_path
else
redirect_to :back
end
end
The _user.html.erb view:
<li><%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
<%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
<% if current_user.admin? && #user != current_user %>
<%=link_to "deactivate", deactivate_path(user_id: #user), method: :post,
data: { confirm: "Are you sure?"}%>
<% end %>
</li>
and the routes:
get 'password_resets/new'
get 'password_resets/edit'
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
post '/deactivate', to: "users#deactivate"
The logs are:
Rendered .../.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_source.erb (9.0ms)
Rendered .../.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_trace.html.erb (3.9ms)
Rendered .../.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_request_and_response.html.erb (1.5ms)
Rendered .../.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/_web_console.html.erb (1.3ms)
Rendered .../.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates/rescues/diagnostics.html.erb within rescues/layout (44.8ms)
What could be wrong? I'm assuming error is in the controller. I am following Michael Hartl tutorial, as I'm a beginner, but I'm also trying to implement thing by myself (like this one).
First of all, you should make this a PUT request rather than POST as it is updating the user record.
Here are the changes that I made to make this work:
Modified the route to PUT in your routes.rb file:
put 'deactivate/:id(.:format)', :to => 'users#deactivate', :as => :deactivate_user
You did not have the implementation for deactivate_account method for your User model. I did that. In your User model:
def deactivate_account
update_attributes!(activated: false)
end
And, finally, changed the user partial like this:
<%=link_to "Deactivate", deactivate_user_path(user), method: :put%>

Routing Error No route matches

I'm trying to get a user from his profile (user_path) can register his vehicles (new_user_car_path). but i got this error:
Routing Error
No route matches {:action=>"new", :controller=>"cars"}
for that i have the next routes.rb
Estaciones::Application.routes.draw do
root :to => "static_pages#home"
match '/contact', :to=>'static_pages#contact'
match '/about', :to=>'static_pages#about'
devise_for :users
resources :users do
resources :cars, :only => [:new, :create, :edit, :destroy]
end
here is part of the user_path
<div class="container">
<fieldset>
<h1><%= #user.email %></h1>
<br>
<h2>options</h2>
<p>
<strong>new car registration</strong>
<%= link_to "Sign up now!", new_user_car_path, :class => "btn btn-primary" %>
</p>
<p>
<strong>all cars view</strong>
</p>
</fieldset>
</div> <!-- /container -->
and my CarsController
class CarsController < ApplicationController
def new
#car = Car.new
end
def create
#car = current_user.cars.build(params[:car])
if #car.save
redirect_to current_user, :flash => { :success => "car created!" }
else
redirect_to new_user_car_path, :flash => { :success => "sorry try again" }
end
end
end
you need to pass information to route, so that it can determine where to go.
if you want to create a new car for a user, you need to pass the user. otherwise rails will not know where to get the user from... which is kind of logical if you think about it for more then a second...
new_user_car_path(user)

Resources