2014-12-08 1 views
2

Полная ошибка:Rails: Нет маршрут не соответствует ... отсутствуют необходимые ключи: [: ID]

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 в действии индекса.

+1

сделать 'edit_reminder_path (ID: reminder.id)' в вашей ссылке – Nithin

+0

У ваших '@ напоминаний' есть объект, который не является БД.Вот почему у него есть id: nil', 'medicication: nil', и только' user_id' не 'nil'. Вы создали его, но не сохранили в БД, возможно, использовали 'Reminder.new' – Nermin

+0

@Nermin - Напоминания были созданы с помощью эшафота. Ошибка начала происходить после того, как я изменил '' '@reminders = Reminders.all'''' '@reminders = current_user.reminders''' в действии индекса. – JeremyE

ответ

11

Причина в том, что вы передаете несохраненный экземпляр «напоминания» в путь edit_reminder_path. Когда вы передаете экземпляр в качестве параметра маршрута, в этом экземпляре вызывается метод to_param. По умолчанию метод to_param возвращает «id» экземпляра.

В вашем случае у вас есть:

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

Потому что вы в области видимости @reminder для текущего пользователя. Этот экземпляр добавляется в коллекцию напоминаний для этого пользователя, поэтому он также включен в @reminders. Это означает, что при рендеринге @reminders на индексной странице он также пытается отобразить несохраненный @reminder, который еще не получил набор «id».

Лучшим решением было бы изменить индексировать действие на:

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 
+0

Ты потрясающий! Спасибо за ответ и объяснение - именно то, что мне нужно! – JeremyE

+0

Ты действительно потрясающий. – Jwan622

2

Ошибка в вашем index действия:

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

Вы добавляете новый экземпляр unpersisted к current_user.reminders коллекции, которая является то, что эта ошибка говорит вам, когда вы итерации, что сбор и попытаться link_to что один: No route matches {:id=>#<Reminder id: nil

0

Bug relatado эм/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 

НУ Десса maneira Решимость о ошибке/или иначе решает эту ошибку

# 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 
Смежные вопросы