tôi nghĩ rằng bạn có nghĩa là hiển thị, vì chỉ mục thực sự là cho danh sách/bộ sưu tập. Và bạn sẽ nhận được .first
về nơi, nếu không bạn chỉ có một mối quan hệ, phải không? Sau đó, sử dụng .first!
để tăng lỗi, bởi vì phần mềm trung gian Rack của Rails trong Rails 4 public_exceptions sẽ xử lý theo kiểu cơ bản, ví dụ:
def show
# need to do to_s on params value if affected by security issue CVE-2013-1854
@bar = Bar.where(:foo_id => params[:id].to_s).first!
end
Bạn cũng có thể sử dụng @bar = Bar.find(params[:id])
, nhưng điều đó bị phản đối và sẽ được loại bỏ trong Rails 4.1, sau đó bạn sẽ phải thêm gem 'activerecord-deprecated_finders'
để Gemfile của bạn để sử dụng.
Đối với chỉ mục, bạn có thể muốn @bars = Bar.all
. Nếu vì một số lý do bạn muốn lọc và không muốn phạm vi, v.v, thì bạn có thể sử dụng @bars = Bar.where(...).to_a
hoặc tương tự.
Rails 4: Basic Xử lý ngoại lệ trong rack là Automatic
Chừng nào truy vấn đá ra một lỗi, Rails 4 sẽ có thể trả lại một phần thông điệp của lỗi cho bất kỳ định dạng được hỗ trợ where to_(format)
có thể được gọi vào băm (ví dụ: json, xml, v.v.)
Để xem lý do tại sao, hãy xem Rails 'Rack public_exceptions middleware.
Nếu là html, nó sẽ cố gắng đọc trong tệp có liên quan từ thư mục công khai trong Rails cho mã trạng thái (ví dụ: 500.html
cho lỗi máy chủ/HTTP 500).
Nếu đó là một số định dạng khác, nó sẽ cố gắng làm to_(the format)
trên băm: { :status => status, :error => exception.message }
.Để xem cách này sẽ làm việc đi đến Rails' console:
$ rails c
...
1.9.3p392 :001 > {status: 500, error: "herro shraggy!"}.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <status type=\"integer\">500</status>\n <error>herro shraggy!</error>\n</hash>\n"
1.9.3p392 :002 > {status: 500, error: "herro shraggy!"}.to_json
=> "{\"status\":500,\"error\":\"herro shraggy!\"}"
Trong middleware, bạn sẽ thấy X-Cascade
tiêu đề trong mã và ở những nơi khác nhau liên quan đến Rails' xử lý ngoại lệ trong rack. Mỗi this answer, tiêu đề X-Cascade
được đặt thành pass
để cho Rack biết các tuyến đường khác để tìm tài nguyên.
Rails 3.2.x: Có thể xử lý ngoại lệ trong rack
Trong Rails 3.2.x, rằng mã để làm to_(format)
cho cơ thể phản ứng, vv không có trong public_exceptions.rb. Nó chỉ xử lý định dạng html.
Có lẽ bạn có thể thử thay thế phần mềm trung gian cũ bằng phiên bản mới hơn qua bản vá.
Nếu bạn muốn Rack xử lý lỗi của bạn theo cách cụ thể hơn mà không cần vá, hãy xem # 3 trong bài đăng của José Valim, "My five favorite “hidden” features in Rails 3.2".
Trong đó và như another answer cũng đề cập đến, bạn có thể sử dụng config.exceptions_app = self.routes
. Sau đó, với các tuyến đường trỏ đến một bộ điều khiển tùy chỉnh, bạn có thể xử lý các lỗi từ bất kỳ bộ điều khiển nào giống như bất kỳ yêu cầu nào khác. Lưu ý bit về config.consider_all_requests_local = false
trong số config/environments/development.rb
của bạn.
Bạn không phải sử dụng tuyến đường để sử dụng exceptions_app
. Mặc dù nó có thể là một chút đáng sợ, nó chỉ là một proc/lambda mà mất một băm và trả về một mảng có định dạng là: [http_status_code_number, {headers hash...}, ['the response body']]
. Ví dụ, bạn sẽ có thể làm điều này trong Rails bạn 3.2.x cấu hình để làm cho nó xử lý các lỗi như Rails 4.0 (đây là public_exceptions middleware mới nhất sụp đổ):
config.exceptions_app = lambda do |env|
exception = env["action_dispatch.exception"]
status = env["PATH_INFO"][1..-1]
request = ActionDispatch::Request.new(env)
content_type = request.formats.first
body = { :status => status, :error => exception.message }
format = content_type && "to_#{content_type.to_sym}"
if format && body.respond_to?(format)
formatted_body = body.public_send(format)
[status, {'Content-Type' => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}",
'Content-Length' => body.bytesize.to_s}, [formatted_body]]
else
found = false
path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
path = "#{public_path}/#{status}.html" unless path && (found = File.exist?(path))
if found || File.exist?(path)
[status, {'Content-Type' => "text/html; charset=#{ActionDispatch::Response.default_charset}",
'Content-Length' => body.bytesize.to_s}, [File.read(path)]]
else
[404, { "X-Cascade" => "pass" }, []]
end
end
end
Lưu ý: Đối với bất kỳ vấn đề với việc xử lý mà , triển khai không an toàn là ở ActionDispatch::ShowExceptions
here.
Rails 3 và 4: Xử lý một số trường hợp ngoại lệ trong Rails khiển
Nếu bạn muốn có vẽ lỗi trong bộ điều khiển chính nó, bạn có thể làm:
def show
respond_with @bar = Bar.where(:foo_id => params[:id].to_s).first!
rescue ActiveRecord::RecordNotFound => e
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
Tuy nhiên, bạn không cần để tăng lỗi. Bạn cũng có thể làm:
def show
@bar = Bar.where(:foo_id => params[:id].to_s).first
if @bar
respond_with @bar
else
respond_to do |format|
format.json => { :error => "Couldn't find Bar with id=#{params[:id]}" }, :status => 404
end
end
end
Bạn cũng có thể sử dụng rescue_from, ví dụ: trong điều khiển của bạn, hoặc ApplicationController, v.v .:
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found(exception)
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
hay:
rescue_from ActiveRecord::RecordNotFound do |exception|
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
Mặc dù một số lỗi phổ biến có thể được xử lý trong điều khiển, nếu bạn sai sót liên quan đến thiếu các tuyến đường vv định dạng trong json , vv, những người cần phải được xử lý trong Rack middleware.