2013-02-28 29 views
6

Tôi có một biểu mẫu để người dùng tạo câu hỏi (trong phần bổ sung cho mô hình người dùng, có mô hình câu hỏi, với câu trả lời lồng nhau) trên trang hồ sơ của họ. Nó gửi từ trang hồ sơ người dùng /views/users/show.html.erb đến hành động tạo của questions_controller.rb. Nếu nó không hợp lệ, tôi nghĩ rằng mặc định cho Rails là biểu hiện biểu mẫu (với thông tin không hợp lệ trong biểu mẫu để người dùng chỉnh sửa). Tuy nhiên, vì tôi đang gửi biểu mẫu cho mô hình câu hỏi từ trang hồ sơ người dùng nên việc lập trước không xảy ra khi xác thực không thành công; người dùng buộc phải nhập lại tất cả thông tin trong biểu mẫu. Có cách nào trong ngữ cảnh này để lấy biểu mẫu trên trang hiển thị của người dùng để điền thông tin đã được nhập trước khi gửi không?Mẫu điền lại khi xác thực không thành công

questions_controller

def create 
    @question = current_user.questions.build(params[:kestion]) 

    if @question.save 
     redirect_to current_user, :notice => "Successfully created question." 
    else 
     ###render :action => 'show' 
     redirect_to current_user 

    end 
    end 

Cập nhật Tôi đã thay đổi khi kết thúc tạo phương pháp quá

Redirect (: back), :notice => "something went wrong.try again" 

Nhưng tôi vẫn không thể lấy mẫu đơn để cư trú, và các thông báo lỗi xác nhận aren không hiển thị một trong hai, chỉ thông báo flash.

Cập nhật Phương pháp hiển thị của bộ điều khiển người dùng tạo ra câu hỏi mới (cùng với người sử dụng)

def show 
     @user = User.find(params[:id]) 
     @question = Question.new 
     3.times {@question.answers.build} 

    end 

Các /views/users/show.html.erb

<%= form_for @question do |f| %> 
    <% if @question.errors.any? %> 
    <h2><%= pluralize(@question.errors.count, "error") %> prohibited this question 
    from being saved: </h2> 
    <ul> 
     <% @question.errors.full_messages.each do |msg| %> 
     <li> <%= msg %></li> 
    <% end %> 
    </ul> 
    <% end %> 
    <p> 
    <%= f.label :content, "Question"%> 
    <%= f.text_area :content, :class => 'span4', :rows => 1 %> 
    </p> 
    <p> 
    <%= f.label :link, "QuoraLink" %> 
    <%= f.text_field :link, :class => 'span4', :rows => 1 %> 
    </p> 
    <%= f.fields_for :answers do |builder| %> 
    <p> 
     <%= render 'answer_fields', :f => builder %> 
    </p> 
    <% end %> 
    <p><%= link_to_add_fields "Add Answer", f, :answers %></p> 
    <p><%= f.submit %></p> 
<% end %> 

các answer_fields được trả lại một phần từ các câu hỏi một phần

<p class="fields"> 
<%= f.label :content, "Answer..." %> 

    <%= f.text_field :content, :class => 'span3', :rows => 1%> 

    <%= f.label :correctanswer, "Correct" %> 
    <%= f.check_box :correctanswer, :class => 'span1' %> 

    <%= link_to_remove_fields "remove answer", f %>  
</p> 
+0

phương thức 'hiển thị' trông như thế nào trong UsersController của bạn? Đây là phương thức mà trước khi điền vào biểu mẫu, như tôi đã hiểu. Ngoài ra, chế độ xem/người dùng/show.html. {Erb, haml} trông như thế nào? Bạn có thể chuyển các tham số ở đó thông qua các tham số đường dẫn hoặc thông qua phiên [], nhưng bạn có thể sẽ cần một số thay đổi ở đó. – moonfly

+0

@moonfly phương thức hiển thị từ trình điều khiển Người dùng 'nên' điền sẵn biểu mẫu (tức là đó là những gì tôi muốn) nếu nó không hiệu quả, nhưng hiện tại nó không thực hiện điều đó. Tôi đã cập nhật OP với mã mà bạn đề nghị tôi hiển thị. Bạn có thể cho tôi biết làm thế nào tôi có thể thay đổi mã trên để prepopulate các hình thức nếu nó không xác nhận với một trong hai phương pháp bạn đề cập đến? – Leahcim

Trả lời

1

Hiện nay, trong views/người dùng/show.rb bạn làm

@question = Question.new 

tạo ra một câu hỏi trống mới. Sau đó, bạn điền các biểu mẫu với mô hình trống này. gì bạn có thể làm thay thế là:

if session[:question] 
    @question = @user.questions.new(session[:question]) 
    session[:question] = nil 
    @question.valid? # run validations to to populate the errors[] 
else 
    @question = Question.new 
end 

Bây giờ tất cả những gì còn lại để làm là Populating phiên [: Câu hỏi] trong questions_controller của bạn trước khi chuyển hướng đến: controller => "người sử dụng",: action => "hiển thị". Một cái gì đó như:

if @question.save 
    redirect_to current_user, :notice => "Successfully created question." 
else 
    session[:question] = params[:question] 
    redirect_to current_user 
end 

Bạn có thể cần phải làm việc trên serialization/deserialization bổ sung cho populating/using session [: question]. Tôi không cố gắng biên dịch, vì vậy tôi không chắc chắn.

Tất cả điều này là cần thiết vì khi bạn chuyển hướng_để xử lý yêu cầu của người dùng kết thúc, trình duyệt của người dùng nhận mã trạng thái chuyển hướng từ máy chủ của bạn và đi đến một trang khác, gửi cho bạn một yêu cầu mới (nằm trên đường dẫn, và cuối cùng là điều khiển/hành động, mà bạn đã chuyển hướng đến). Vì vậy, ngay khi bạn quay trở lại từ xử lý yêu cầu, tất cả các biến của bạn đều bị mất. Đối với yêu cầu tiếp theo bạn bắt đầu từ đầu.

Cách tiếp cận render :action => "show" (nằm trong khung ban đầu và bạn đã nhận xét) đã hoạt động vì bạn không trả lại cho người dùng nhưng chỉ cần hiển thị mẫu với tên cụ thể bằng các biến mà bạn đã có sẵn tại chỗ (bao gồm @ câu hỏi, trong đó 'lưu' được gọi và không thành công, và do đó xác thực nội bộ được gọi và điền vào đối tượng lỗi).

Thực ra, điều đó nhắc tôi rằng bạn có thể muốn sử dụng cách tiếp cận khác. Thay vì truyền các tham số thông qua phiên [] và chuyển hướng đến UsersController, bạn có thể muốn điền tất cả các biến bắt buộc và chỉ hiển thị khung nhìn từ bộ điều khiển đó. Giống như bên dưới:

if @question.save 
    redirect_to current_user, :notice => "Successfully created question." 
else 
    @user = current_user 
    render "users/show" 
end 
+0

Tôi đã thử đề xuất thứ hai hiển thị "người dùng/chương trình" nhưng đã gặp sự cố. Ở đầu /views/users/show.html.erb Tôi có một phần điều hướng cụ thể cho tài nguyên người dùng. Phần điều hướng bị thiếu khi hiển thị người dùng/hiển thị từ bộ điều khiển câu hỏi – Leahcim

+0

Giải pháp phiên là hứa hẹn (nghĩa là tôi có thể điền lại trường câu hỏi), nhưng bạn sẽ nhận thấy rằng tôi không chỉ tạo câu hỏi mới trong hành động hiển thị của mình, mà còn ba trường trả lời - 3.times {@ question.answers.xây dựng} - làm thế nào để tôi có được những thứ đó để tái hiện lại thông tin về phiên? – Leahcim

1

Thứ nhất, lý do sử dụng redirect_to thay vì render không lặp lại biểu mẫu là khi bạn redirect_to, logic bộ điều khiển cho hành động được chạy, trong khi sử dụng render bỏ qua logic điều khiển.

Vì vậy, khi bạn render :action => 'show' (the "mặc định" hành vi), nó ám show.html.erb, với @question bộ như thế này:

@question = current_user.questions.build(params[:kestion]) 

Khi bạn redirect_to current_user, nó ám show.html.erb với @question bộ bằng cách sử dụng mã trong hành động show của bạn :

@question = Question.new 
3.times {@question.answers.build} 

Đây là lý do tại sao bạn nhận biểu mẫu mới (trống) thay vì mẫu được điền trước.

Có phải thực sự là quan trọng là bạn sử dụng redirect_to? Nếu có, bạn sẽ cần phải nhận phương thức show để thực hiện xác thực. Ví dụ, bạn có thể viết lại phương pháp show của bạn để một cái gì đó như:

def show 
    @user = User.find(params[:id]) 
    if params.has_key?(:kestion) 
    @question = @user.questions.build(params[:kestion]) 
    else 
    @question = Question.new 
    3.times {@question.answers.build} 
    end 
end 

và sau đó làm điểm hình thức của bạn tại trang đó, với một cái gì đó như:

<%= form_for(@question, url: users_path(@question.user) do |f| %> 
    ... 
<% end %> 

(tùy thuộc vào cách tuyến đường của bạn được thiết lập và được đặt tên).Tất nhiên, vào thời điểm đó toàn bộ điều trở nên khủng khiếp un-RESTful, một chút của một mớ hỗn độn, và chắc chắn không phải là cách Rails làm việc. (Tùy chọn khác, tệ hơn là chuyển hướng ngược lại và chuyển các tham số thông qua truy vấn nhận được.) Theo ý kiến ​​của tôi, bạn sẽ mất rất nhiều lợi ích nhỏ và tôi không chắc chắn rằng tôi thực sự khuyên bạn nên.

+0

Tôi đồng ý với bình luận 'khủng khiếp un-RESTful'. @ Michael, nếu tôi có ý định của bạn đúng, bạn dường như muốn cải thiện giao diện người dùng và cho phép chỉnh sửa các câu hỏi tại chỗ trong biểu mẫu người dùng. Nếu bạn làm điều đó, thì có lẽ nó có ý nghĩa để thực hiện bước hợp lý tiếp theo và lưu/xác nhận các câu hỏi trong phương thức cập nhật UsersController #. Thả các QuestionsController hoàn toàn và để cho UsersController chăm sóc cả hai mô hình - Người dùng và Câu hỏi. – moonfly

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