完整错误:
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
后,错误开始发生。
答案 0 :(得分:11)
这样做的原因是您将未提交的“提醒”实例传递到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
答案 1 :(得分:2)
错误发生在您的index
操作中:
def index
@reminders = current_user.reminders
@reminder = current_user.reminders.new # <== HERE
end
您正在向current_user.reminders
集合中添加一个新的未加载的实例,当您迭代该集合并尝试链接到该集合时,此错误会告诉您:No route matches {:id=>#<Reminder id: nil
答案 2 :(得分:0)
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解决o 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