【问题标题】:Rails: No route matches ... missing required keys: [:id]Rails:没有路线匹配...缺少必需的键:[:id]
【发布时间】:2015-02-05 19:51:36
【问题描述】:

完全错误:

No route matches {:id=>#<Reminder id: nil, medication: nil, time: nil, created_at: nil, updated_at: nil, user_id: 1>} missing required keys: [:id]

这是导致错误的 index.html.erb 中的代码:

<tbody>
    <% @reminders.each do |reminder| %>
      <tr <%= dom_id(reminder) %>>
        <td><%= reminder.medication %></td>
        <td><%= reminder.time %></td>
        <td>
          <%= link_to "Edit", edit_reminder_path(reminder) %>
          or
          <%= link_to 'Remove', reminder, method: :delete, data: { confirm: 'Are you sure?' } %>
      </td>
      </tr>
    <% end %>
  </tbody>

型号:

class Reminder < ActiveRecord::Base
    validates :medication, presence: true
    belongs_to :user
end
class User < ActiveRecord::Base
  has_many :reminders
end

动作:

  def index
    @reminders = current_user.reminders
    @reminder = current_user.reminders.new 
  end
  def edit
  end

路线:

Medy::Application.routes.draw do
  devise_for :users
  resources :reminders
  root 'reminders#index'
end

我是否需要在编辑操作中添加一些内容才能完成这项工作?

在我将索引操作中的@reminders = Reminders.all 更改为@reminders = current_user.reminders 后,错误开始发生。

【问题讨论】:

  • 在你的链接中做edit_reminder_path(id: reminder.id)
  • 您的@reminders 具有非数据库持久化的对象。这就是为什么它有id:nilmedication: nil,并且只有user_id 不是nil。你有没有创建过但没有保存到DB,可能用过Reminder.new
  • @Nermin - 提醒是使用脚手架创建的。在我将索引操作中的@reminders = Reminders.all 更改为@reminders = current_user.reminders 后,错误开始发生。
  • @Nithin - 也没有运气。
  • @Nithin : 非常感谢 nithin ..你的想法解决了我的问题

标签: ruby-on-rails routes


【解决方案1】:

原因是您将未保存的“提醒”实例传递到 edit_reminder_path 中。当您将实例作为参数传递给路由时,会在该实例上调用“to_param”方法。默认情况下,“to_param”方法返回实例的“id”。

在你的情况下,你有:

def index
  @reminders = current_user.reminders
  @reminder = current_user.reminders.new
end

因为您已将@reminder 范围限定为当前用户。该实例被添加到该用户的提醒集合中,因此也包含在@reminders 中。这意味着当您在索引页面上渲染@reminders 时,它也会尝试渲染尚未设置“id”的未保存@reminder。

更好的解决方案是将索引操作更改为:

def index
  @reminders = current_user.reminders
  @reminder = Reminder.new
end

然后在您保存提醒时,很可能是在“创建”操作中,您将范围限定为 current_user:

def create
  @reminder = current_user.reminders.new(reminder_params)
  if @reminder.save .....
end

【讨论】:

  • 你太棒了!感谢您的回答和解释——正是我所需要的!
  • 你真的很棒。
【解决方案2】:

错误在于您的index 操作:

def index
  @reminders = current_user.reminders
  @reminder = current_user.reminders.new # <== HERE
end

您正在向current_user.reminders 集合添加一个新的非持久化实例,这就是当您迭代该集合并尝试链接到该集合时该错误告诉您的内容:No route matches {:id=&gt;#&lt;Reminder id: nil

【讨论】:

    【解决方案3】:

    Bug relatado em / Bug 报告于 https://github.com/rails/rails/issues/12178

    class ApplicationController < ActionController::Base
      protect_from_forgery
      before_action :set_locale
    
      def default_url_options(options={})
        { locale: I18n.locale }
      end
    
      private
        def set_locale
          I18n.locale = params[:locale] || I18n.default_locale
        end
    end
    

    ou dessa maneira resolve o bug / 或者那样解决 bug

    # app/controllers/application_controller.rb
    def default_url_options(options = {})
      { locale: I18n.locale }.merge options
    end
    

    Ficaria assim /看起来像这样

    # app/controllers/application_controller.rb
    class ApplicationController < ActionController::Base
          protect_from_forgery
          before_action :set_locale
    
         def default_url_options(options = {})
          { locale: I18n.locale }.merge options
         end
    
          private
            def set_locale
              I18n.locale = params[:locale] || I18n.default_locale
            end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-09
      相关资源
      最近更新 更多