ruby-on-rails Rails 7:Turbo调用不存在的create方法

vwoqyblh  于 2023-01-03  发布在  Ruby
关注(0)|答案(1)|浏览(126)

我遇到了一个问题。在我的Rails应用程序中,我试图使用给定的select-option元素加载一个数据列表。当我点击提交时,我收到一个错误消息,create方法在我的控制器中不存在(这是真的)。我是这个turbo-rails包的新手,但这是我目前得到的结果:
索引.html.erb

<!DOCTYPE html>
<html>
    <head>
        <%= stylesheet_link_tag 'users/main', 'data-turbolinks-track': 'reload' %>
        <%= csrf_meta_tags %>
    </head>
    <body>
        <main>
            <div class="grid">
                <div class="users">
                    <div class="filters">
                        <form action="/users" method="POST">
                            <input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>">
                            <%= render partial: "shared/select", locals: {
                                placeholder: 'Gender', 
                                width: '90px', 
                                options: $genders,
                                classes: 'filter',
                                name: 'gender'
                            } %>

                            <button type="submit">submit</button>

                        </form>
                    </div>

                    <div id="user-data-list">
                        <%= render partial: "users/user_list", locals: {
                            users: @users
                        } %>
                    </div>  
                </div>
            </div>
        </main>
    </body>
</html>

用户控制器rb

class UsersController < ApplicationController

    before_action :require_user

    USERS_PER_PAGE = 15

    def index
        @users = User.limit(USERS_PER_PAGE).order(:creation_date).reverse_order
    end

    def load
        gender = if params[:gender] then params[:gender] else '' end

        @users = User.limit(USERS_PER_PAGE).where(
            "gender LIKE ?", "%" + gender + "%"
        ).order(:creation_date).reverse_order

        respond_to do |format|
            format.turbo_stream
            format.html { redirect_to users_url() }
        end
    end
end

加载.turbo_流.erb

<%= turbo_stream.replace "user-data-list" do %>
    <%= render partial: "users/user_list", locals: {
        users: @users
    } %>
<% end %>

路由.rb

Rails.application.routes.draw do
  # System check
  get '/health', to: 'application#health'

  get '/users' => "users#index"
  post '/users' => "users#load"
  resources :users

  post '/login' => 'auth#login'
  get '/logout' => 'auth#logout'
end

_选择.html.erb

<!DOCTYPE html>
<html>
    <head>
        <%= stylesheet_link_tag 'components/select', media: 'all', 'data-turbolinks-track': 'reload' %>
    </head>
    <body>
        <select
            style="<%= 'width: ' + width + ';' if width %>"
            <% if defined?(id) %>
                id="<%= id %>"
            <% end %>
            <% if defined?(classes) %>
                class="<%= classes %>"
            <% end %>
            <% if defined?(name) %>
                name="<%= name %>"
            <% end %>
            <% if defined?(required) %>
                required
            <% end %>
        >
            <option 
                value="" 
                disabled 
                selected 
                hidden
            >
                <%= placeholder %>
            </option>

            <% options.each do |option| %>
                <option><%= option %></option>
            <% end %>
        </select>
    </body>
</html>

但是当我运行这段代码并点击提交按钮时,我得到了以下错误:

我的控制器中没有create方法,因为没有创建用户的选项。我有一个自定义的load方法,但我似乎不明白它为什么要调用create方法。有人能给我解释一下吗?

q3qa4bjr

q3qa4bjr1#

路由的优先级按其声明的顺序排列。
resources :users已经声明了一个POST /users路由,虽然你可以通过将你的奇怪路由上移来修复它,但你实际上根本不需要这样做。
你所做的看起来就像是在给一个资源添加一堆过滤器,你可以通过向集合路径(索引)发送一个GET请求,并让它使用可选的查询字符串参数来应用条件。

Rails.application.routes.draw do
  # System check
  get '/health', to: 'application#health'

  # Only declare the routes you're actually using!
  resources :users, only: [:index]

  post '/login' => 'auth#login'
  get '/logout' => 'auth#logout'
end
<%= form_with(url: users_path, method: :get,  data: { turbo_frame: "user-data-list" }) do |form| %>
  <%= render partial: "shared/select", locals: {
                                placeholder: 'Gender', 
                                width: '90px', 
                                # why is this a global?
                                options: $genders,
                                classes: 'filter',
                                name: 'gender',
                                form: form # pass the form builder along
                            } %> 

  <%= form.submit %>
<% end %>
# /app/users/index.turbo_stream.erb
<%= turbo_stream.replace "user-data-list" do %>
    <%= render partial: "users/user_list", locals: {
        users: @users
    } %>
<% end %>
class UsersController < ApplicationController
  before_action :require_user
  USERS_PER_PAGE = 15

  def index
    @users = User.limit(USERS_PER_PAGE)
                 .order(:creation_date: :desc)
    if params[:gender] 
      # and why is this pattern matching? 
      @users.where("gender LIKE ?", "%#{gender}%")
    end

    respond_to do |format|
      format.turbo_stream
      format.html
    end
  end
end

从概念上讲,通过查询字符串参数执行搜索、添加分页或任何其他类型的过滤器都是幂等操作,因为它不会创建或更改任何内容,并且对于使用相同URI的任何访问者来说,资源看起来都是相同的(至少在理论上是这样)。
因此,应该使用GET而不是POST,这样可以将请求保存在浏览器历史记录中--缓存,并直接链接。

相关问题