【问题标题】:Problem calling a controller method from view从视图调用控制器方法的问题
【发布时间】:2019-11-16 21:26:01
【问题描述】:

我有一个带有以下方法的 Books 控制器:

books_controller.rb

  def set_as_reading
    if (user_signed_in?)
     if (current_user.user_type == "0")
        @book = Book.find(params[:id])
        @reading = Reading.new
        @reading.book_id = @book.id
        @reading.profile_id = session[:current_profile]["id"]
        @reading.is_finished = false
        @reading.save 
      else
        redirect_to books_path
      end
    else
      redirect_to root_path
    end
  end

  def remove_from_reading
    if (user_signed_in?)
      if (current_user.user_type == "0")
        @book = Book.find(params[:id])
        @reading = Reading.where(profile_id: session[:current_profile]["id"]).where(book_id: @book.id)
        @reading.is_finished = true
        @reading.save
      else
        redirect_to books_path
      end
    else
      redirect_to root_path
    end
  end

我已经定义了以下路线:

routes.rb

  post 'books/:id', to: 'books#set_as_reading', as: :set_as_reading
  post 'books/:id', to: 'books#remove_from_reading', as: :remove_from_reading

我在显示视图中使用这些方法如下:

show.html.erb

  <% if current_user.user_type == "0" %> 
    <%= link_to "Add to Reading list", @book, method: :set_as_reading, class: 'btn btn-danger',
    style: 'margin-right:10px' %>
    <%= link_to "Finished", @book, method: :remove_from_reading, class: 'btn btn-danger',
    style: 'margin-right:10px' %>
  <% end %> 

每当我单击“添加到阅读列表”时,它都会正常工作,它会调用set_as_reading 方法。但是如果我想设置为“完成”,而不是调用remove_from_reading,它调用set_as_reading。 我怎样才能解决这个问题?提前谢谢你。

编辑

rake 路由输出:

                   books GET    /books(.:format)                       books#index
                         POST   /books(.:format)                       books#create
                new_book GET    /books/new(.:format)                   books#new
               edit_book GET    /books/:id/edit(.:format)              books#edit
                    book GET    /books/:id(.:format)                   books#show
                         PATCH  /books/:id(.:format)                   books#update
                         PUT    /books/:id(.:format)                   books#update
                         DELETE /books/:id(.:format)                   books#destroy
          set_as_reading POST   /books/:id(.:format)                   books#set_as_reading
     remove_from_reading POST   /books/:id(.:format)                   books#remove_from_reading

【问题讨论】:

  • 因为它们在 rout.rb 文件中有相同的路径?
  • 你能贴出该部分的rails路线吗?
  • 只需为每个功能更改您的路线,看看您的应用程序如何运行并告诉我好吗?
  • @KickButtowski 我应该修改哪一个以及如何修改?

标签: ruby-on-rails ruby routes custom-routes


【解决方案1】:

问题是您有一条路线指向两个不同的地方。 Rails 只会抓取它看到的第一个。

每条路线都必须是唯一的:

post 'books/:id/reading', to: 'books#set_as_reading', as: :set_as_reading
post 'books/:id/finished', to: 'books#remove_from_reading', as: :remove_from_reading

此外,您的嵌套 if 语句并不总是会导致重定向。

如果我已登录并且我的 user_type 为“0”,那么在 @reading.save 完成后我应该发送到哪里?

而且你的代码很胖。它可以更清洁。

我建议是这样的:

class BooksController < ApplicationController
  before_action :set_book, only: %w[set_as_reading remove_from_reading]
  before_action :check_user, only: %w[set_as_reading remove_from_reading]

  def set_as_reading
    @reading = Reading.create(
      book: @book,
      profile_id: session[:current_profile]["id"], # is this the same as current_user?? If so, just use current_user.id
      is_finished: false
    )

    redirect_to somewhere_path # this is missing currently
  end

  def remove_from_reading
                                         # is this the same as current_user?? If so, just use current_user.id
    @reading = Reading.where(profile_id: session[:current_profile]["id"]).where(book_id: @book.id)

    # what happens if no record is found??
    redirect_to somewhere_path and return unless @reading.present?

    @reading.update(is_finished: true)

    redirect_to somewhere_path and return # this is missing currently
  end

  private

  def set_book
    @book = Book.find(params[:id])
  end

  def check_user
    redirect_to root_path unless user_signed_in? and return

    redirect_to books_path unless current_user.user_type == '0' and return
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    相关资源
    最近更新 更多