Действие уничтожения Rails не работает с button_to

Я новичок в Rails и в настоящее время работаю над своим проектом. Идея состоит в том, что когда пользователь покупает что-то для кого-то, он может создать транзакцию с такой информацией, как мы: для кого он купил, сколько он потратил и, наконец, короткий описание перевода. Я создал столбец администратора в базе данных «Пользователи» и инициализировал пользователя-администратора. Я ограничил доступ к действию index только для администратора - администратор работает нормально. Я хочу, чтобы администратор мог уничтожать транзакции, перечисленные в представлении индекса. То, что я написал для достижения этого, не работает. Вот скриншот представления индекса: https://i.stack.imgur.com/pK1Rg.png

Мой код в представлениях/транзакциях/индексе

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

Мои маршруты

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

Мой контроллер

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

Когда я нажимаю «Удалить», вот что происходит в журналах: https://i.stack.imgur.com/A1HU8.png Меня перенаправляют на root_path — странно, посмотрите на действие create. Я не понимаю, почему он говорит о недопустимом параметре: :transaction_id. Я тоже не понимаю, почему после нажатия на Удалить мелькает сообщение: Вы совершили транзакцию! происходит. Такая вспышка должна происходить при создании действия. Вот html:

Буду признателен за любую помощь.

Вот часть кода helpers/session_helper, связанная с 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 

person L.Wini    schedule 15.07.2020    source источник


Ответы (1)


Добро пожаловать в SO @L.Wini.

Для этой конкретной проблемы я предлагаю вам пару вещей:

  1. В файле 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'

так как у вас есть: resources :transactions (это генерирует их все для вас).

  1. В index.html.erb нет необходимости использовать button_to:
<%= button_to "Delete", action: "destroy", method: :delete,
           params: { transaction: { transaction_id: transaction.id } } %>

Вместо этого вы можете использовать link_to:

<%= link_to 'Destroy', transaction, method: :delete, data: { confirm: 'Are you sure?' } %>
  1. Действие destroy будет принимать только params[:id]:
def destroy 
  @transaction = Transaction.find(params[:id])
  @transaction.destroy
  flash[:success] = "Transaction has been removed!"
  redirect_to transactions_path
end 

Это должно помочь вам решить проблему удаления.

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.

Удачного кодирования!

Ссылка: https://guides.rubyonrails.org/action_controller_overview.html

person Violeta    schedule 15.07.2020
comment
Спасибо за ваш ответ. А как насчет действия контроллера destroy. Rails не знает, какую транзакцию хочет уничтожить администратор. Как я должен предоставить Rails такую ​​информацию, используя link_to? Кстати: Да, мне не нужны маршруты, которые вы указали, за одним исключением для сообщения '/transactions/:id', до: 'transactions#edit'. - person L.Wini; 15.07.2020
comment
Мои извинения @L.Wini, я забыл включить в ответ действие по уничтожению. Я отредактировал свой ответ. Посмотрите и дайте мне знать, если это сработало, и если у вас есть вопросы. Спасибо - person Violeta; 15.07.2020
comment
Тем не менее, не работает. Вот вывод журнала Начато DELETE /transactions/1 для ::1 в 2020-07-15 15:53:12 +0200 Обработка TransactionsController#destroy как HTML Параметры: {authenticity_token=>[Я удалил токен, соответствующий сообщению об ошибке], id=›1} User Load (0,2 мс) SELECT users.* FROM users WHERE users.id = ? ПРЕДЕЛ ? [[id, 22], [LIMIT, 1]] ↳ app/helpers/session_helper.rb:27:in current_user' Completed 500 Internal Server Error in 6ms (ActiveRecord: 0.2ms | Allocations: 1664) NoMethodError (undefined method []' для nil:NilClass): - person L.Wini; 15.07.2020
comment
Похоже, журналы указывают на app/helpers/session_helper.rb, строку 27, метод current_user. Я думаю, что проблема может быть в этом, но я также не вижу требуемого входа для пользователя внутри transactions_controller.rb в before_action. @Л.Вини - person Violeta; 15.07.2020
comment
Я только что отредактировал свой первоначальный пост с кодом в app/helpers/session_helper.rb. - person L.Wini; 15.07.2020