Rails - 将数据添加到关系的关系 table

Rails - add data to relation's relation table

我有 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


一张照片属于一个问题和一个答案。但是您尝试创建属于多个 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

首先,p[:title]a[:image] 等并不是 ruby 式的(此外,您在每个方法调用中输入了三个额外的字符,而且,您知道,人生苦短。)只需执行 p.titlea.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

我不确定你是否真的想要所有那些重复的Photo(也许你想要)。但是,如果你不这样做,我想我会做类似的事情:

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 对象(您只真正想要那些 id),您可能会查看 .pluck.