5

Xin lỗi nếu câu hỏi là hiển nhiên, tôi chỉ bắt đầu làm việc với Rails.
Tôi có một đoạn mã sau vào một số phương pháp điều khiển bây giờ:Rails Newbie: Khuyến nghị xử lý lỗi trong bộ điều khiển

respond_to do |format| 
    if @project.save 
     format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } 
     format.js 
    else 
     format.html { render :action => "edit" } 
     format.js #... 
    end 
end 

Vậy câu hỏi là, cách tốt nhất để làm điều tương tự cho các lỗi trong tất cả các phương pháp là gì?
Tôi có nên sử dụng save! và xử lý nó trong rescue_action?

Hoặc tôi có nên tự mình làm phương pháp respond và vượt qua save trong một khối không?

Trả lời

16

Thường thuận tiện hơn khi sử dụng biến thể lưu và cứu ngoại lệ mà sau này trong khối so với chi nhánh như vậy. Lợi thế của trường hợp ngoại lệ là họ sẽ phá vỡ các giao dịch.

def create 
    @project.save! 

    respond_to do |format| 
    format.html { redirect_to(edit_project_url(@project), :notice => '#{user.name} added to #{role}.') } 
    format.js 
    end 

rescue ActiveRecord::RecordInvalid 
    respond_to do |format| 
    format.html { render :action => "edit" } 
    format.js #... 
    end 
end 

Bạn sẽ thấy rằng nó được thực sự khó khăn để wrangle theo cách của bạn ra khỏi một đống lồng nhau if báo cáo khi cố gắng tiết kiệm nhiều hơn một đối tượng tại một thời điểm, nhưng một đơn giản rescue cho trường hợp ngoại lệ sẽ xử lý nó gọn gàng .

def create 
    Project.transaction do 
    @project.save! 
    @something_else.save! 
    @other_stuff.save! 
    end 

    # ... 
rescue ActiveRecord::RecordInvalid 
    # ... 
end 

Nếu một trong số đó tiết kiệm được, bạn sẽ nhận được ngoại lệ. Để đảm bảo rằng tất cả chúng đều hiển thị các lỗi xác thực, bạn có thể phải gọi .valid? trên mỗi số để đánh dấu chúng hoặc bạn sẽ có những lỗi sau khi lỗi không được kiểm tra.

+0

Điều này có vẻ là một ý tưởng tốt, nhưng tại sao giàn giáo không đi theo con đường này? Ngoài ra tôi giả sử bạn khuyên bạn nên sử dụng 'rescue_action' nếu có một số phương pháp như vậy? –

+0

Ok, tôi sẽ giả sử bạn có nghĩa là một 'rescue_from' hoặc' rescue_action_in_public' handler cho nhiều phương thức, trong trường hợp này, Chubas trả lời ở đây là một tập hợp con của cái này và tôi nên chấp nhận câu trả lời này. –

+0

Như một quy tắc chung, tôi sử dụng 'rescue_from' cho những thứ không thể dễ dàng phục hồi, và' rescue' khi tôi có thể xử lý nó. Khi một 'tạo' thất bại, thông thường bạn chỉ cần hiển thị lại biểu mẫu' mới'. Một cái gì đó trừu tượng hơn thường trả về một trang "Uh oh" khá. – tadman

3

Không phải là điều xấu khi sử dụng mẫu if @object.save. Tuy nhiên, nếu bạn đang làm chính xác như nhau cho tất cả các hành động của bạn trên bộ điều khiển của bạn, bạn có thể xác định một hành động rescue_from.

Something like

class MyController < ActionController::Base 
    rescue_from ActiveRecord::RecordInvalid do 
    render :action => edit 
    end 
end 
+0

Vâng, đó là một trong những lựa chọn của tôi, nhưng kiểu này cần phiên bản '!', Phải không? Bạn có biết tại sao giàn giáo không đi theo cách này theo mặc định? Nó có vẻ tốt hơn với tôi. –

+0

Cả hai bạn và @tadman đều dường như bổ sung cho nhau, vì vậy tôi sẽ chấp nhận cả hai nếu tôi có thể, nhưng tiếc là tôi phải chọn một. –

Các vấn đề liên quan