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

时间:2019-09-23 18:37:55

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

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


2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

首先,执行p[:title]a[:image]等并不是红宝石。(此外,每个方法调用要键入三个额外的字符,而且寿命很短。 )只需执行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)

相反,您尝试调用photos返回的可枚举的q.answers.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用作适当的红宝石对象(您只真正想要那些id s),因此您可以考虑使用.pluck