我的Rails应用中有SaleQualifier
个对象。每个人都会在SalesOpportunity
展示页面上找到预先确定的(并通过YAML预加载)问题,然后构建答案sale_qualifier has_one answer
。这两个项目都要保存到数据库中,之后我使用answer_type和answer_text来确定接下来应该向用户显示哪个问题。
我认为我的代码中存在某种无限循环,但我无法弄清楚它是什么。当我有一个sale_qualifier has_many answers
关系时,这种方法很好,但是一旦我将关系更改为has_one
关系,它就会崩溃。
我的代码:
def show
@sales_opportunity = SalesOpportunity.includes(:company, :user, :timeline_events, :sale_contacts, :swots, :sale_competitors).find(params[:id])
@sale_qualifier = SaleQualifier.new(sales_opportunity_id: params[@sales_opportunity.id])
@answer = @sale_qualifier.answers.build
#if the question_id is blank it is the first question in the list
if @sale_qualifier.question_id.blank?
@question = Question.find_by_id(@sale_qualifier.next_question_id)
else
@question = Question.find_by_id(@sale_qualifier.question_id)
end
end
这只是设置show动作,所以我可以显示添加答案的表单:
<div class="panel panel-default">
<%= form_for(@sale_qualifier) do |f| %>
<% if @sale_qualifier.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@sale_qualifier.errors.count, "error") %> prohibited this answer from being saved:</h2>
<ul>
<% @sale_qualifier.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="panel-body">
<div class="col-sm-6">
<h2><%= @question.question_text %></h2>
</div>
<div class="col-sm-6">
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
<%= f.hidden_field :question_id, :value => @question.id %>
</div>
<%= f.fields_for :answers do |answer| %>
<%= answer.text_area :answer_text, :placeholder => "Enter your answer" %>
<% end %>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-large btn-success"%>
</div>
<% end %>
</div>
</div>
提交后,由SaleQualifier创建方法处理:
def create
@sale_qualifier = SaleQualifier.new(sale_qualifier_params)
respond_to do |format|
if @sale_qualifier.save
format.html { redirect_to @sale_qualifier, notice: 'Sale qualifier was successfully created.' }
format.json { render :show, status: :created, location: @sale_qualifier }
else
format.html { render :new }
format.json { render json: @sale_qualifier.errors, status: :unprocessable_entity }
end
end
end
但我认为错误发生在我已添加到Answer和SaleQualifier模型的方法中:
class Answer < ActiveRecord::Base
validates :answer_text, presence: true
belongs_to :sale_qualifier
after_save :update_sale_qualifier
def update_sale_qualifier
sale_qualifier.update_next_question
sale_qualifier.save
end
end
class SaleQualifier < ActiveRecord::Base
has_one :answer, :inverse_of => :sale_qualifier, dependent: :destroy
accepts_nested_attributes_for :answer
belongs_to :sales_opportunity
validates :sales_opportunity_id, presence: true
def update_next_question
#find the question that this SaleQualifier is associated with
question = Question.find_by_id(self.question_id)
#get its answer_type as this defines whether we need to look at the next_question_id_no or not
ans_type = question.answer_type
if ans_type == 'Text Field' || ans_type == 'Datetime' || ans_type == 'Integer' || ans_type == 'Boolean' && self.answer.answer_text == 'True'
self.next_question_id = question.next_question_id_yes
#if the answer_type is a boolean and the answer is no/false, then use the next_question_id_no to route the question
elsif ans_type == 'Boolean' && self.answer.answer_text == 'False'
self.next_question_id = question.next_question_id_no
end
#mark the question as answered, in case we need to iterate over the same quesiton in future
self.has_answer = true
#create a new SaleQualifier with the question set as the next question, unless it already exists and hasn't been answered yet or unless the next question id leads us to a result (i.e. no questions left in the tree)
SaleQualifier.create(question_id: self.next_question_id, sales_opportunity_id: self.sales_opportunity_id) unless Question.exists?(:id => self.next_question_id) || SaleQualifier.find_by(question_id: self.next_question_id) && SaleQualifier.find_by(question_id: self.next_question_id).has_answer == false
end
end
我收到以下错误:
Completed 500 Internal Server Error in 730ms
SystemStackError (stack level too deep): actionpack (4.1.1) lib/action_dispatch/middleware/reloader.rb:79
我假设这里有一个命名空间错误,因为我可能会使用“&#34; answer&#34;我的模型字段名称太多了。有人能帮我找到吗?
修改
错误正在循环执行以下一组SQL操作:
SQL (0.6ms) UPDATE "answers" SET "answer_text" = $1, "created_at" = $2, "id" = $3, "sale_qualifier_id" = $4, "updated_at" = $5 WHERE "answers"."id" = 6 [["answer_text", "Because they're Grrrreat!"], ["created_at", "2016-01-13 09:19:46.172878"], ["id", 6], ["sale_qualifier_id", 8], ["updated_at", "2016-01-13 09:19:46.172878"]]
Question Load (0.5ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = 1 LIMIT 1
Question Exists (0.5ms) SELECT 1 AS one FROM "questions" WHERE "questions"."id" = 2 LIMIT 1
CACHE (0.0ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = 1 LIMIT 1
SQL (0.4ms) UPDATE "sale_qualifiers" SET "created_at" = $1, "has_answer" = $2, "id" = $3, "next_question_id" = $4, "question_id" = $5, "sales_opportunity_id" = $6, "updated_at" = $7 WHERE "sale_qualifiers"."id" = 8 [["created_at", "2016-01-13 09:19:46.164754"], ["has_answer", "t"], ["id", 8], ["next_question_id", 2], ["question_id", 1], ["sales_opportunity_id", 77], ["updated_at", "2016-01-13 09:19:46.164754"]]
SQL (0.3ms) UPDATE "answers" SET "answer_text" = $1, "created_at" = $2, "id" = $3, "sale_qualifier_id" = $4, "updated_at" = $5 WHERE "answers"."id" = 6 [["answer_text", "Because they're Grrrreat!"], ["created_at", "2016-01-13 09:19:46.172878"], ["id", 6], ["sale_qualifier_id", 8], ["updated_at", "2016-01-13 09:19:46.172878"]]
Question Load (0.6ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = 1 LIMIT 1
Question Exists (0.4ms) SELECT 1 AS one FROM "questions" WHERE "questions"."id" = 2 LIMIT 1
(0.4ms) ROLLBACK