Full error:
No route matches {:id=>#<Reminder id: nil, medication: nil, time: nil, created_at: nil, updated_at: nil, user_id: 1>} missing required keys: [:id]
Here is the code from index.html.erb that is causing the error:
<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>
Models:
class Reminder < ActiveRecord::Base
validates :medication, presence: true
belongs_to :user
end
class User < ActiveRecord::Base
has_many :reminders
end
Actions:
def index
@reminders = current_user.reminders
@reminder = current_user.reminders.new
end
def edit
end
Routes:
Medy::Application.routes.draw do
devise_for :users
resources :reminders
root 'reminders#index'
end
Do I need to add something to the edit action to make this work?
The error started happening after I changed @reminders = Reminders.all
to @reminders = current_user.reminders
in the index action.
The reason for this is that you are passing an unsaved instanced of 'reminder' into the edit_reminder_path. When you pass an instance as a parameter to a route the 'to_param' method is called on that instance. By default the 'to_param' method returns the 'id' of the instance.
In your case you have:
def index
@reminders = current_user.reminders
@reminder = current_user.reminders.new
end
Because you have scoped the @reminder to the current user. That instance is added to the collection of reminders for that user, and so is also included in @reminders. This means that when you are rendering out the @reminders on the index page, It also tries to render out the unsaved @reminder which has not yet got an 'id' set.
A better solution would be to change you index action to:
def index
@reminders = current_user.reminders
@reminder = Reminder.new
end
And then at the point that you save the reminder, most likely in a 'create' action, you would scope to the current_user:
def create
@reminder = current_user.reminders.new(reminder_params)
if @reminder.save .....
end
The error is in your index
action:
def index
@reminders = current_user.reminders
@reminder = current_user.reminders.new # <== HERE
end
You're adding a new unpersisted instance to the current_user.reminders
collection, which is what this error is telling you when you iterate that collection and try to link_to that one: No route matches {:id=>#<Reminder id: nil
Bug relatado em / Bug reported in
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 / or that way solves the bug
# app/controllers/application_controller.rb
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
Ficaria assim /would look like this
# 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