【问题标题】:Rails - add data to relation's relation tableRails - 将数据添加到关系的关系表中
【发布时间】:2019-09-23 18:37:55
【问题描述】:

我有 questionsanswersphotos models。我将paperclip 用于图像。

我无法使用以下代码将answer's image 添加到photos table

 q = Question.new(
            title:  p[:title],
            post:  p[:post]
            )

p[:answers].each do |a|
  q.answers.build(body: a[:body])
  if a[:images]
    a[:images].each do |e|
      q.answers.photos.create(image: e) #this line gives the error
    end
  end
end

错误行q.answers.photos.create(image: e)

错误是:

undefined method `photos' for #<Answer::ActiveRecord_Associations_CollectionProxy:0x00007f9592208800>

我为我的模型创建了关联,例如:

class Answer < ApplicationRecord
 belongs_to :question
 has_many :photos
end

class Photo < ApplicationRecord
  belongs_to :question
  belongs_to :answer

  has_attached_file :image,
                    :path => ":rails_root/public/img/:filename", validate_media_type: false

  do_not_validate_attachment_file_type :image
end


【问题讨论】:

  • 尝试create方法而不是build
  • 错误是由create方法引起的,而不是build方法引起的。
  • 你为什么用p[:answer](例如)而不是p.answer

标签: ruby-on-rails ruby ruby-on-rails-5 paperclip


【解决方案1】:

一张照片属于一个问题和一个答案。但是您尝试创建属于多个q.answers 的照片。

你可能想做这样的事情:

question = Question.new(title: p[:title], post: p[:post])

p[:answers].each do |a|
  answer = q.answers.create(body: a[:body])
  if a[:images]
    a[:images].each do |e|
      answer.photos.create(image: e, question: q)
    end
  end
end

【讨论】:

  • 出于好奇,由于answer 没有保存,answer.photos.create 可以正常工作吗?
  • @jvillian 好问题。其实我不确定。查看has_many 的Rails 指南并没有给出答案。最好先创建答案。即使没有必要,您也会在验证失败时收到更好的错误消息。
  • 感谢您的回答,但现在我收到了rollback transaction 的图片。我错过了什么吗?我不使用任何验证do_not_validate_attachment_file_type :image
  • 我认为原因是联想。但我无法解决。
【解决方案2】:

首先,p[:title]a[:image] 等不是 ruby​​-ish。(此外,每次方法调用您要输入三个额外的字符,而且,你知道,生命很短暂。)只需执行 @ 987654323@、a.image 等。因此,您的代码应如下所示:

q = Question.new(title: p.title, post: p.post)

p.answers.each do |answer|
  q.answers.build(body: answer.body)
  if answer.images
    answer.images.each do |image|
      q.answers.photos.create(image: image)
    end
  end
end

现在,您想为您在此处实例化的 answer 创建新照片:

q.answers.build(body: answer.body)

相反,您尝试在q.answers.photos 返回的枚举上调用photos。而且,自然地,那个可枚举(在这种情况下是ActiveRecord_Associations_CollectionProxy)没有那个方法。所以,你得到了undefined method 错误。

你可以试试:

q = Question.new(title: p.title, post: p.post)

p.answers.each do |answer|
  new_answer = q.answers.build(body: answer.body)
  if answer.images
    answer.images.each do |image|
      new_answer.photos.create(image: image)
    end
  end
end

除非你还没有保存new_answer,所以它没有id。在这种情况下,它可能仍然会出错。

所以,也许:

q = Question.new(title: p.title, post: p.post)

p.answers.each do |answer|
  new_answer = q.answers.create(body: answer.body)
  if answer.images
    answer.images.each do |image|
      new_answer.photos.create(image: image)
    end
  end
end

我不确定你是否真的想要所有重复的Photos(也许你想要)。但是,如果你不这样做,我想我会这样做:

class AnswerPhoto < ApplicationRecord
  belongs_to :answer
  belongs_to :photo
end

class Answer < ApplicationRecord
  belongs_to :question
  has_many :answer_photos
  has_many :photos, through: :answer_photos
end

class Photo < ApplicationRecord
  belongs_to :question
  has_many :answer_photos
  has_many :answers, through: :answer_photos
end

在这种情况下,您可能会执行以下操作:

q = Question.new(title: p.title, post: p.post)

p.answers.each do |answer|
  new_answer = q.answers.create(body: answer.body)
  new_answer.photos << answer.photos
end

在我看来,您正在那里进行一些 N+1 查询,因此您需要查看 .include。而且,由于您并没有真正使用 answer.photos 作为正确的 ruby​​ 对象(您只需要那些 ids),您可能会查看 .pluck

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多