尝试创建新数据时会显示以下错误。
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_to
new_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
如果你能给我任何建议,我们将不胜感激。
答案 0 :(得分:0)
首先,我建议从路径文件中删除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
答案 1 :(得分:0)
在您的事件控制器中,在new
操作中,将其更改为@room = @event.room
。您的错误是说找不到room_id。你在控制器中编写它的方式是你要求你的新方法将@ event.room设置为@room,但这是该方法第一次看到@room并且不知道它是什么。通过说@room = @ event.room,新动作可以理解,就像你已经在上面的行中一样,定义了@event是什么,所以将room_id分配给@event。