本文介绍了Rails4:Formtastic3.0,同时保存多个实例(用于Answer模型)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题模型和答案模型。

每个用户每个问题可以有一个答案。我试图预设给用户一个表单来回答所有问题,但无法真正弄清楚如何用formtastic做到这一点。



这是我迄今为止

p>

   -  @ questions.each do | q | 
= q.content
- ans = @ user.answers.where(question_id:q.id).first.try(:content)|| q.description
= semantic_form_for @answers do | f |
= f.label q.content
= f.inputs:content,placeholder:ans
= f.actions

我试图从这里是我的尝试,不起作用:

   -  semantic_form_for:Answer,:url => api_v1_answers_path,:method => :把do | f | 
- @ questions.each do | q |
- f.fields_for'questions []',q do | ff |
= q.content
= ff.input
= submit_tagSubmit

注意:

1]在添加/编辑所有答案后,我希望只有用户按下一次提交

2]如果答案已经存在,它应该在文本框中预先填充。

3]我不介意使用simple_form gem如果这样可以让生活更轻松

解决方案

然后为 @questions 您需要将单个对象传递给您的表单助手( @questions 是一组问题)。实现此目的的一种好方法是使用。

 #app / forms / questions_form.rb 
class QuestionsForm
包含ActiveModel :: Model

def initialize (user)
@user = user
end

def questions
@questions || = Question.all
end

def submit(params)
params.questions.each_pair do | question_id,answer |
answer = Answer.find_or_initialize_by(question_id:question_id,user:current_user)
answer.content = answer
answer.save
end
end

def answer_for(question)
answer = answers.select {| answer | answer.question_id == question.id}
answer.try(:content)
end
$ b def答案
@answers || = @ user.answers.where (question:questions)
end
end

然后在你的控制器中, d有:

 #app / controllers / submissions_controller.rb 
Class SubmissionsController< / p> ApplicationController
...
def new
@questions_form = QuestionsForm.new(current_user)
end
$ b def创建
@questions_form = QuestionsForm .new(current_user)

@ questions_form.submit(params [:questions_form])
redirect_to#where-ever
end
...
end

在您的视图中,您需要遵循以下内容:

 #app / views / submissions / new.html.haml 
= form_for @questions_form,url:submissions_path do | f |
- @ questions_form.questions.each do | question |
%p = question.content
= f.text_fieldquestions [#{question.id}],value:@ questions_form.answer_for(question)
= f.submitSubmit

这根本不使用formtastic,它只是使用plain rails形式助手。



这段代码没有经过测试,因此不确定它是否可以正常工作,但希望它能帮助您找到正确的轨道。


I have Question model and an answer model.

Each question can have one answer per user. I am trying to preset to a user a form to answer all questions, but couldnt really figure out how to do it with formtastic

Here is what I have so far

    - @questions.each do |q|
      = q.content
      - ans = @user.answers.where(question_id:q.id).first.try(:content) || q.description
      = semantic_form_for @answers do |f|
        = f.label q.content
        = f.inputs :content, placeholder: ans
      = f.actions

I am trying to get some hint from How to loop through two alternating resources on a form? but I keep getting "undefined method `model_name' for Class:Class" for @questions if I try:

= semantic_form_for @questions do |q|
  = q.input :content
  = q.semantic_fields_for @answer do |a|
    = a.inputs :content
  = q.actions

Based on Railscast 198, but using formtastic here is my attempt that doesn't work either:

- semantic_form_for :Answer, :url => api_v1_answers_path, :method => :put do |f|
  - @questions.each do |q|
    - f.fields_for 'questions[]', q do |ff|
      = q.content
      = ff.input
  = submit_tag "Submit"

Note:

1] I will like to have user press submit only once after he has added/edited all the answers

2] If there is an answer already present, it should be pre-poulated in the text box

3] I dont mind using simple_form gem if that makes life easier

解决方案

Rather then making a form for @questions you need to pass a single object to your form helper (@questions is an array of questions). A good way to achieve this is though a form object.

# app/forms/questions_form.rb
class QuestionsForm
  include ActiveModel::Model

  def initialize(user)
    @user = user
  end

  def questions
    @questions ||= Question.all
  end

  def submit(params)
    params.questions.each_pair do |question_id, answer|
      answer = Answer.find_or_initialize_by(question_id: question_id, user: current_user)
      answer.content = answer
      answer.save
    end
  end

  def answer_for(question)
    answer = answers.select { |answer| answer.question_id == question.id }
    answer.try(:content)
  end

  def answers
    @answers ||= @user.answers.where(question: questions)
  end
end

Then in your controller you'd have:

# app/controllers/submissions_controller.rb
Class SubmissionsController < ApplicationController
  ...
  def new
    @questions_form = QuestionsForm.new(current_user)
  end

  def create
    @questions_form = QuestionsForm.new(current_user)

    @questions_form.submit(params[:questions_form])
    redirect_to # where-ever
  end
  ...
end

In your view you'll want something along the lines of:

# app/views/submissions/new.html.haml
= form_for @questions_form, url: submissions_path do |f|
  - @questions_form.questions.each do |question|
    %p= question.content
    = f.text_field "questions[#{question.id}]", value: @questions_form.answer_for(question)
  = f.submit "Submit"

This doesn't use formtastic at all, it's just using the plain rails form helpers.

This code isn't tested so not sure if it even works but hopefully it helps get you on the right track.

这篇关于Rails4:Formtastic3.0,同时保存多个实例(用于Answer模型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 06:52