Reputation: 67
I am a beginner in Rails and currently I am working on my project.The idea is, that when user buy something for someone, it can create a transaction with informations such us: for who it bought, how much it spent and finally a short description of transaction. I had created an admin column in database Users and initialized an admin user. I restricted access to index action only for admin - admin works fine. I want admin to be able to destroy transactions that are listed in the index view.What I wrote in order to achieve that does not work. Here is a screenshot of index view: https://i.sstatic.net/pK1Rg.png
My code in views/transactions/index
<ul>
<% @transactions.each do |transaction| %>
<li>
<%= transaction.user_id %> |
<%= transaction.borrower_name %> |
<%= transaction.value %>
<%= button_to "Delete", action: "destroy", method: :delete,
params: { transaction: { transaction_id: transaction.id } } %>
</li>
<% end %>
</ul>
My routes
Rails.application.routes.draw do
root 'static_pages#home'
get '/about', to: 'static_pages#about'
get '/help', to: 'static_pages#help'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'session#new'
post '/login', to: 'session#create'
delete '/logout', to: 'session#destroy'
get '/transactions', to: 'transactions#index'
post '/transactions/new', to: 'transactions#create'
get '/transactions/new', to: 'transactions#new'
post '/transactions/:id', to: 'transactions#edit'
delete '/transactions', to: 'transactions#destroy'
resources :users
resources :transactions
end
My controller
class TransactionsController < ApplicationController
#skip_before_action :is_logged_in?, only: [:index]
#before index and destroy action run check_admin -> ensure access only for admin user
before_action :check_admin?, only: [ :index, :destroy ]
def new
@transaction = Transaction.new
end
def create
#current_user
@transaction = current_user.transactions.build(transaction_params)
#check if borrower_name exists in db - it must exists to make a transaction
check = User.find_by(name: params[:transaction][:borrower_name])
if check != current_user
@transaction.save
flash[:success] = "You have made a transaction!"
redirect_to root_path
elsif check == current_user
flash[:danger] = "You try to make a transaction for yourself!"
render 'transactions/new'
else
flash[:danger] = "Something went wrong!Probably, the borrower is not registed."
render 'transactions/new'
end
end
def index
@transactions = Transaction.all
end
def edit
#get transactions where current_user borrows money from someone
@transaction = Transaction.where(id: params[:transaction][:transaction_id])
if params[:transaction][:active]
@transaction.update(active: params[:transaction][:active], activated_at: Time.zone.now)
else
@transaction.update(active: params[:transaction][:active])
end
redirect_to transaction_path(current_user)
end
def show
#grab the transactions assosiated with the user -
#user lends money - passive transactions
if current_user
#current_user lends money
@lend_transaction = current_user.transactions
#current_user borrows money
@borrow_transaction = Transaction.where(borrower_name: current_user.name)
end
end
def destroy
@transaction = Transaction.find(params[:transaction][:transaction_id])
@transaction.destroy
flash[:success] = "Transaction has been removed!"
redirect_to transactions_path
end
private
def transaction_params
params.require(:transaction).permit(:borrower_name, :value)
end
def check_admin?
#check if current_user has admin => true
redirect_to root_url unless current_user.admin
end
end
When I click on "Delete" here is what happens in logs: https://i.sstatic.net/A1HU8.png I get redirected to root_path - weird, look at the create action. I don't understand why it says "Unpermitted parameter: :transaction_id". I also don't understand why after I click on "Delete" a flash with message: "You have made a transaction!" occurs.Such flash should occur in create action. Here is the html:
I would appreciate any help.
Here is a helpers/session_helper code part related with current_user:
#method to determine a current user
module SessionHelper
def current_user
#if there is a session -> use session hash
if session[:user_id]
#nil or equal
@current_user ||= User.find_by(id: session[:user_id])
#if there are cookies -> use cookies to operate log in
elsif cookies.encrypted[:user_id]
#find the user by the encrypted user_id key
user = User.find_by(id: cookies.encrypted[:user_id])
#if user exists and the remember token authentication succeed
#log in and set @current_user to user
if user && user.authenticated?(cookies[:remember_token])
log_in(user)
@curent_user = user
end
end
end
Upvotes: 0
Views: 739
Reputation: 710
Welcome to SO @L.Wini.
For this particular issue, I'll suggest you couple things:
routes
file, you don't need these routes:get '/transactions', to: 'transactions#index'
post '/transactions/new', to: 'transactions#create'
get '/transactions/new', to: 'transactions#new'
post '/transactions/:id', to: 'transactions#edit'
delete '/transactions', to: 'transactions#destroy'
since you have: resources :transactions
(this is generating all of them for you).
index.html.erb
there's no need to use button_to
:<%= button_to "Delete", action: "destroy", method: :delete,
params: { transaction: { transaction_id: transaction.id } } %>
Instead, you can use link_to
:
<%= link_to 'Destroy', transaction, method: :delete, data: { confirm: 'Are you sure?' } %>
destroy
action will accept params[:id]
only:def destroy
@transaction = Transaction.find(params[:id])
@transaction.destroy
flash[:success] = "Transaction has been removed!"
redirect_to transactions_path
end
This should help you solve the delete issue.
If you're interested in improving the code you have for the other actions, let me know and I'll try to help you out.
Happy coding!
Reference: https://guides.rubyonrails.org/action_controller_overview.html
Upvotes: 2