【问题标题】:Rails: ActionController::UrlGenerationError, No route matches, missing required keysRails:ActionController::UrlGenerationError,没有路由匹配,缺少必需的键
【发布时间】:2016-06-23 13:42:21
【问题描述】:

当我尝试创建新数据时显示以下错误。

ActionController::UrlGenerationError (No route matches {:room_id=>nil, :action=>"index", :controller=>"events"} missing required keys: [:room_id]):

模型

models/rooms.rb

      has_many :events, inverse_of: :room, dependent: :destroy
      has_many :amounts, inverse_of: :room, dependent: :destroy
      accepts_nested_attributes_for :events, allow_destroy: true

models/events.rb

      has_one :amount, inverse_of: :schedule, dependent: :destroy
      accepts_nested_attributes_for :amount, allow_destroy: true

routes.rb

...
  resources :events,              only: [:new, :create, :edit, :update]

  resources :rooms do
    resources :events
  end

...

当我单击link_tonew_room_event_path(1) 时,会显示上述错误。 它生成root/rooms/1/events/new

查看

    <% if logged_in? %>
      <% if current_user?(@user) %>
        <% if schedule.rooms.blank? %>
          <%= link_to "Add event", new_room_event_path(1), class: "btn btn-sn btn-primary" %>
          <br>
        <% end %>
      <% end %>
    <% end %>

之所以指定new_room_event_path(1),是因为这是第一次创建数据。

events_controller.rb

  before_action :load_room

  def new

    @event = Event.new
    @event.room = @room
    @event.build_amount
    @event.amount.schedule = @room.schedule
    @event.amount.room = @room

  end

  private

    def load_room
      if Room.exists?(id: params[:room_id])
        @room = Room.find(params[:room_id])
      else
        @room = Room.new
      end
    end

如果您能给我任何建议,我们将不胜感激。

【问题讨论】:

  • 是否至少创建了一个房间?因为您似乎在传递硬代码值,所以我问这个...

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


【解决方案1】:

首先,我建议从路由文件中删除 resources :events, only: [:new, :create, :edit, :update],因为您将事件用作房间下的嵌套资源。

其次,如果您要创建一个不存在的房间,最好将它们发送到可以创建房间的实际 new_room_path ,如果您希望它们成为嵌套形式,您可以将其设为嵌套形式能够在创建新房间的同时添加事件。如果房间已经存在,那么您可以使用 new_room_event_path(room) 设计的嵌套路由

您的事件模型中似乎缺少与房间的关联,别忘了

# models/event.rb

belongs_to :room

然后您可以从您的 EventsController 中执行此操作,而不必担心零空间

# controllers/events_controller.rb

before_action :set_room
before_action :set_event, only: [:show, :edit, :update, :destroy]

private

def set_room
  @room = Room.find(params[:room_id])
end

def set_event
  @event = Event.find(params[:id])
end

有关嵌套资源的更多详细信息,请参阅http://guides.rubyonrails.org/routing.html#nested-resources

【讨论】:

    【解决方案2】:

    在您的事件控制器中,在 new 操作中,将其更改为 @room = @event.room。您的错误是找不到 room_id。您在控制器中编写它的方式是要求您的新方法将@event.room 设置为@room,但这是该方法第一次看到@room 并且不知道它是什么。通过说@room = @event.room,新操作可以理解为您已经在上面的行中定义了@event 是什么,因此将room_id 分配给该@event。

    【讨论】:

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