Ruby - find_or_intialize_by不分配属性

时间:2017-09-06 11:38:04

标签: ruby-on-rails ruby

我试图使用find_or_initialize_by然而它没有像应该那样分配属性..我有以下内容:

vote
=> #<AnswerRecord id: 3926, stage_record_id: 2210, stage_answer_id: nil, value: "{:stage_answer_id=>1563}", correct: false, created_at: "2017-09-06 11:33:49", updated_at: "2017-09-06 11:33:49", deleted_at: nil>

当我输入binding.pry时,我可以看到以下内容:

value: "{:stage_answer_id=>1563}" 

由于某种原因,它正在分配

stage_answer_id: 1563

而不是

class AnswerRecord < ActiveRecord::Base

  acts_as_paranoid

  belongs_to :stage_record
  belongs_to :stage_answer
  has_one :activity_feedback

  def self.for_answer(answer)
    find_by(stage_answer: answer)
  end

  def wrong?
    !correct
  end
end

我做错了什么?提前致谢

编辑:answer_record.rb

>> opinion
=> #<AnswerRecord id: nil, stage_record_id: nil, stage_answer_id: 1692, value: "This is my answer", correct: true, created_at: nil, updated_at: nil, deleted_at: nil>
>> opinion.save
!! #<ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR:  null value in column "value" violates not-null constraint
DETAIL:  Failing row contains (3938, 2222, 1692, null, f, 2017-09-06 12:03:09.851213, 2017-09-06 12:03:09.851213, null).
: INSERT INTO "answer_records" ("stage_answer_id", "stage_record_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id">

第二次编辑: 更多来自byebug:

show-method record.answer_records.find_or_initialize_by

由于日志显示PSQL正在尝试更新其他属性而不是“&#39;值”&#39;属性,我没有设置任何初始化器。

第三次编辑:

From: /Users/mark/.rvm/gems/ruby-2.3.2/gems/activerecord-4.2.7.1/lib/active_record/relation.rb @ line 223:
13:15:53 web.1  | Owner: ActiveRecord::Relation
13:15:53 web.1  | Visibility: public
13:15:53 web.1  | Number of lines: 3
13:15:53 web.1  | 
13:15:53 web.1  | def find_or_initialize_by(attributes, &block)
13:15:53 web.1  |   find_by(attributes) || new(attributes, &block)
13:15:53 web.1  | end

返回以下内容

{{1}}

1 个答案:

答案 0 :(得分:1)

您必须了解find_or_initialize_by的工作原理,查看来自show-method的代码,您必须看到它是:

 def find_or_initialize_by(attributes, &block)
   find_by(attributes) || new(attributes, &block)
 end

所以在你的情况下它就像:

record.answer_records.find_by(stage_answer_id: vote_id) ||
record.answer_records.new(stage_answer_id: vote_id)

我认为您认为自己正在调用新内容,但可能您已经拥有匹配stage_product_idstage_answer_id的记录,因此永远不会调用.new。并且可能该记录使value文本字段混乱。

您可以调用.persisted?方法来验证记录是新的还是来自DB,并检查控制台中的DB日志:

vote_id = 1534
vote = record.answer_records.find_or_initialize_by(stage_answer_id: vote_id)
puts vote.persisted?

值得注意的是,@ tom-lord在我前面的TabLayout提出答案