【问题标题】:No route matches {:action=>"show", :controller=>"scoo.....missing required keys: [:id]没有路线匹配 {:action=>"show", :controller=>"scoo.....缺少必需的键:[:id]
【发布时间】:2016-12-14 06:19:53
【问题描述】:

我有一个用于创建和更新的部分表单...对于新的它呈现部分但在进行编辑时我不断收到此错误

ActionController::UrlGenerationError in Scoopes#edit
no route matches {:action=>"show", :controller=>"scoopes", :id=>nil, :user_name=>#<Scoope id: 11, name: "asdsada", user_id: 3, created_at: "2016-08-07 20:37:52", updated_at: "2016-08-07 20:37:52">} missing required keys: [:id]

我从旧问题中寻找答案,但没有人解决我的问题...该表格用于创建独家新闻...

scoope 和用户之间的关联是:

scoope belong_to user
and user has_many scoopes

这是我的勺子控制器:

class ScoopesController < ApplicationController
  before_action :authenticate_user!, except: [:show]
  before_action :set_scoope, only: [:show, :edit, :update, :destroy, :index]
  before_action :owned_scoope, only: [:edit, :update, :destroy]

  def index
    @scoopes = @user.scoopes.all
  end

  def show
    @scoope = @user.scoopes.find(params[:id])
  end

  def new
    @scoope = current_user.scoopes.build
  end

  def create
    @scoope = current_user.scoopes.build(scoope_params)
    if @scoope.save
        redirect_to scoope_path(current_user.user_name, @scoope)
    else
        render 'new'
    end
  end

  def edit
    @scoope = @user.scoopes.find(params[:id])
  end

  def update
    @scoope = @user.scoopes.find(params[:id])
    if @scoope.update(scoope_params)
        redirect_to scoope_path(@user, @scoope)
    else
        render 'edit'
    end
  end


  def destroy
    @scoope = @user.scoopes.find(params[:id])
    @scoope.destroy
    redirect_to scoopes_path
  end

  private

  def scoope_params
    params.require(:scoope).permit(:name)
  end

  def set_scoope
    @user = User.find_by(user_name: params[:user_name])
  end
  def owned_scoope
    unless @user == current_user
        flash[:danger] = "this scope dont belong to you"
        redirect_to root_path
    end
  end
end

这是我的部分表单(我认为问题可能与编辑路径有关,因为当我尝试用 edit_scoope_path 替换 scoope 时,它​​会在编辑页面下呈现表单......但它不会解决我的鲸鱼问题,因为它是部分):

<div class="row">
  <div class="col-md-5 formm">
    <%= render 'shared/errors', obj: @scoope %>
    <div class="well">
      <%= form_for @scoope do |f| %>
        <div class="form-group">
          <%= f.label :name %><br/>
          <%= f.text_area :name, rows: 6, class: 'form-control' %>
        </div>
        <div class="form-group">
          <%= f.submit class: 'btn btn-primary'  %> <%= link_to "Back", :back, class: "btn btn-danger" unless current_page?(scoopes_path) %>
        </div>
      <% end %>
    </div>
  </div>
</div>

这是我的scoopes路线:

               scoopes GET    /:user_name/scoopes(.:format)               scoopes#index
                     POST   /:user_name/scoopes(.:format)               scoopes#create
          new_scoope GET    /:user_name/scoopes/new(.:format)           scoopes#new
         edit_scoope GET    /:user_name/scoopes/:id/edit(.:format)      scoopes#edit
              scoope GET    /:user_name/scoopes/:id(.:format)           scoopes#show
                     PATCH  /:user_name/scoopes/:id(.:format)           scoopes#update
                     PUT    /:user_name/scoopes/:id(.:format)           scoopes#update
                     DELETE /:user_name/scoopes/:id(.:format)           scoopes#destroy

我的勺子桌:

create_table "scoopes", force: :cascade do |t|
  t.string   "name"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

路线:

devise_for :users, :controllers => { :registrations => "user/registrations" }
root "posts#index" 
scope '/:user_name' do
 resources :scoopes
end
get ':user_name', to: 'profiles#show', as: :profile  
get ':user_name/edit', to: 'profiles#edit', as: :edit_profile  
patch ':user_name/edit', to: 'profiles#update', as: :update_profile  
................

【问题讨论】:

  • 请发布 routes.rb
  • 在您进行编辑调用时,您的控制台日志是否显示 id 正在传递?
  • @Deepak 我添加了你现在可以看到的路线
  • @MarsAtomic 如果你在这里谈论这个是.. 参数:{"user_name"=>"Sam Abunu", "id"=>"11"} that 错误前显示的 id在日志中
  • @Tobias 感谢您的改进

标签: ruby-on-rails ruby forms ruby-on-rails-4 routes


【解决方案1】:

您的呼叫失败,因为您使用的是nested route,正如scoope belongs to user 关系所定义的那样。

routes.rb中,你可以在userscoope之间设置ReSTful路由,如下:

resources :users do
  resources :scoopes
end

这个符号应该给你你需要的嵌套路由:

edit_user_scoope_path

要组织user_name 下的嵌套对象,请尝试:

scope "/:user_name" do
  resources :posts
end

这应该给你这样的路线:

edit_scoope GET /:user_name/scoopes/:id/edit(.:format) scoopes#edit

【讨论】:

  • 好的,但我想在路由中使用 user_name 而不是 user_id,这里它给了 user_id
  • 我也不想要 user/:user_name/scoopes/:id...如果您注意到我在路由中的 url 是 :user_name/scoopes/:id 因为scoopes 与用户个人资料 url 相关.. . 所以例如我的个人资料网址是 localhost:3000/Sam%20Abunu 如果我想检查相关的勺子我通过 localhost:3000/Sam%20Abunu/scoopes 但在你的例子中它会改变我所有的计划......! !
  • 这种方法仍然不起作用...我找到了另一种在不改变路线的情况下运行良好的方法。我添加了这个 @scoope.persisted? ? scoope_path(@scoope.user.user_name, @scoope) : scoopes_path(current_user.user_name) 做 |f| %>,无论如何,谢谢你的帮助......你的方法给了我一些我以前不知道的新东西......所以再次感谢
  • 第二个例子应该给你你想要的,那么“这个方法不起作用”是什么意思?
  • 对我不起作用,表格也不起作用,它在路线上给了我这两件事,1- user_scoopes GET /users/:user_id/scoopes ..... 2- scoopes GET / :user_name/scoopes ...以及它为我提供了一个新的用户路由,其中​​包含我不想要的 id ....我想要的只是保留范围“/:user_name”做资源:posts 结束而不添加任何路由并修复表单
【解决方案2】:

问题在于您的routes.rb 文件。您可以添加如下嵌套路由:

resources :users do
  resources :scoopes
end 

这将输出如下所示的 url。从这个输出中你可以清楚地看到路径将是 user_scoope_path(current_user, @scoope)

                                                                                                                                             scoopes#index
                                                            POST     /users/:user_id/scoopes(.:format)                                          scoopes#create
                                            new_user_scoope GET      /users/:user_id/scoopes/new(.:format)                                      scoopes#new
                                           edit_user_scoope GET      /users/:user_id/scoopes/:id/edit(.:format)                                 scoopes#edit
                                                user_scoope GET      /users/:user_id/scoopes/:id(.:format)                                      scoopes#show
                                                            PATCH    /users/:user_id/scoopes/:id(.:format)                                      scoopes#update
                                                            PUT      /users/:user_id/scoopes/:id(.:format)                                      scoopes#update
                                                            DELETE   /users/:user_id/scoopes/:id(.:format)                                      scoopes#destroy

希望对您有所帮助。

【讨论】:

  • 好的,但我想在路由中使用 user_name 而不是 user_id,这里它给了 user_id
  • 哦,我的错,你可以像下面这样改变你的routes.rb:`resources :users, :key => :user_name do resources:scoopes end` 然后像user_scoope_path(current_user.user_name, @scoope)一样调用
  • 我没有测试它,但应该可以正常工作。记住,在你的表演动作中你应该使用@scoope = @user.scoopes.find(params[:user_name])
  • 仍然有 user_id 但也不是我想要的...我不想要 user/:user_name/scoopes/:id...如果你注意到我在路由中的 url 是 :user_name/scoopes/: id,因为 Scoopes 与用户个人资料 url 相关
  • 所以例如我的个人资料网址是localhost:3000/Sam%20Abunu,如果我想检查相关的独家新闻,我会通过localhost:3000/Sam%20Abunu/scoopes,但在你的例子中它会改变我所有的计划......!!跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多