我使用的是rails 4.2。我创建了一个表单,提交给我的控制器中的特定操作。这是表单代码和控制器定义的开头:
view.html.erb
<div id="account-booking" class="tab-pane">
<%= form_for @booking_info, url: { action: 'book' } do |b| %>
<fieldset class="group column-1">
<legend>Booking Preference for <%= Rails.configuration.x.app_settings.year %></legend>
<div class="group column-full radio-list">
<%= label_tag('Select Room Type') %>
<% @available_rooms.each do |rt| %>
<div class="radio-item">
<!--
<%= b.radio_button :room_type_id, rt.id, :class => 'rb_room_type inline', :onclick => fetch_room_info_path(:id => rt.id), :remote => true %>
<%= b.radio_button :room_type_id, rt.id, :class => 'rb_room_type inline', :onclick => 'render_room_info('+ rt.id.to_s + ');' %>
-->
<%= b.radio_button :room_type_id, rt.id, :class => 'rb_room_type inline' %>
<%= content_tag :span, rt.name %>
<a data-toggle="tooltip" data-placement="right" title="<%= rt.description %>">
<%= image_tag "tooltip.png", :class=>"tooltip-icon" %>
</a>
</div>
<% end %>
<%= b.label :roommate_preference, 'Roommate Preference' %>
<%= b.text_area :roommate_preference, :class => 'form-control' %>
<div class="account-checkbox-options">
<%= b.label :is_flexible, class: 'checkbox inline' do %>
<%= b.check_box :is_flexible %>
I am flexible with regards to my room choice.
<% end %>
</div>
</div>
<!--
<div id="estimated-due" class="group column-2">
</div>
-->
</fieldset>
<fieldset class="group column-2 account-preferences">
<legend>Your Room Information for <%= Rails.configuration.x.app_settings.year %></legend>
<div class="group column-1">
<div class="group column-full add-tabbing">
<%= label_tag('Selected Room:') %>
<span><%= @booking_info.room_type.blank? ? '<No Room Selected>' : @booking_info.room_type.name %></span>
</div>
<div class="group column-full add-tabbing">
<%= label_tag('Assigned Room:') %>
<span><%= @booking_info.assigned_type.blank? ? '<No Room Assigned>' : @booking_info.assigned_type.name %></span>
</div>
</div>
<div class="group column-2">
<div class="group column-full add-tabbing">
<%= label_tag('Total Due:') %>
<span ><%= number_to_currency(@booking_info.total_due.blank? ? 0.00 : @booking_info.total_due) %></span>
</div>
<div class="group column-full add-tabbing">
<%= label_tag('Current Balance:') %>
<span><%= number_to_currency(@booking_info.outstanding_balance.blank? ? 0.00 : @booking_info.outstanding_balance) %></span>
</div>
</div>
<% unless @booking_info.assigned_type.blank? %>
<div class="group column-full">
<h2>Assigned Room Information</h2>
</div>
<% end %>
</fieldset>
<div class="account-buttons">
<%= b.submit 'Submit', class: 'btn btn-danger' %>
<%= link_to 'Cancel', '/pages/home', class: 'link-button-cancel' %>
</div>
<% end %>
</div>
account_controller.rb
def book
@booking = PersonRoom.new(booking_params)
@requested_room = RoomType.find(params[:person_room][:room_type_id])
@booking.room_type = @requested_room
if update_booking @booking
redirect_to :controller => 'account', :action => 'view'
else
render('view')
end
end
当没有PersonRoom记录时(如果我正在进行插入),所有这些都可以很好地工作。但是,如果我尝试更新记录,使用相同的表单/操作(因为无论我是否插入或更新,视图和操作都完全相同),当我点击&时,我收到错误#34;提交&#34;:
没有路线匹配[PATCH]&#34; / account / book&#34;
这没有任何意义。我在完全相同的页面上。我刚刚使用了所有这些代码来创建记录,因此路径显然存在(因为它调用/ account / book)。现在我想更新,但突然之间路线不匹配?它甚至从未打破过代码,因为它没有调用控制器动作。这对我来说毫无意义。希望有人可以提供帮助。
答案 0 :(得分:0)
我发现了问题。这真是太愚蠢了。我在route.config中有以下行:
match ':controller(/:action(/:id))', :via => [:get, :post]
我只需将其更改为:
match ':controller(/:action(/:id))', :via => [:get, :post, :patch, :put, :delete]
现在它处理更新(即补丁/放置)
答案 1 :(得分:0)
在查看您的代码时我畏缩了,这是我如何做到的:
#config/routes.rb
resources :rooms do
resources :bookings #-> url.com/rooms/:room_id/bookings/new
end
#app/controllers/bookings_controller.rb
class BookingsController < ApplicationController
before_action :set_room
def new
@booking = room.bookings.new
end
def create
@booking = room.bookings.new booking_params
@booking.save
end
def update
@booking = room.bookings.update booking_params
end
private
def set_room
@room = Room.find params[:room_id]
end
def booking_params
params.require(:booking).permit(:x, :y, :z)
end
end
此设置与Rails(IE resourceful routes)非常标准:
浏览器通过使用URL请求来自Rails的页面 特定的HTTP方法,例如GET,POST,PATCH,PUT和DELETE。每 method是对资源执行操作的请求。一个 资源路由将许多相关请求映射到a中的操作 单控制器。
遵守这一原则可能会解决你的“怪异”问题。路由错误是由于它们与Rails系统的其他方面的凝聚力。
例如:
#app/controllers/accounts_controller.rb
class AccountsController < ApplicationController
#-> this shouldn't have a "book" action unless necessary. Your case is not necessary
end
-
你遇到的问题是你没有遵守Rails&#39;保持系统面向对象的惯例。
这一点的重要性是巨大的; Rails旨在使CRUD (create read update destroy)数据对象尽可能简单。这些对象是根据&#34; models&#34;中的数据库数据构建的:
我经常使用这张图片 - 它显示了Rails应该如何工作。您可以在控制器中操作的Models
中构建对象。视图向用户显示了所有内容。
因此,当您查看代码时,我会尽量保持简单:
#app/models/room.rb
class Room < ActiveRecord::Base
has_many :bookings
has_many :users, through: :bookings
belongs_to :type
end
#app/models/booking.rb
class Booking < ActiveRecord::Base
belongs_to :room
belongs_to :user
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :bookings
has_many :rooms, through: :bookings
end
这将允许您拨打以下电话:
@room = Room.find 1
@room.bookings #-> collection of bookings per room
您还可以为视图执行以下(简单)操作:
#app/views/bookings/new.html.erb
<%= form_for @booking do |f| %>
<%= f.text_field :x %>
<%= f.text_field :y %>
<%= f.text_field :z %>
<%= f.submit %>
<% end %>