2015-09-18 1 views
1

Я получаю XML-файл, который я должен проанализировать. Из него я беру данные для двух моделей. Продукт и приложение. Вложение - это изображение для продукта. Это как код идет, я буду следовать за этим объяснением:Массив вложенных атрибутов, заданный как параметр хэша

def add_to_db_from_file 
    transaction do 
     save! 
     xml = Nokogiri::XML(File.open(self.file.current_path)) 
     xml.xpath("//item").each do |item| 
      product_hash = %w[campaign_name widget_name title description short_message price category 
                subcategory url product_id aff_code].each_with_object({}) do |n, h| 
                 h[n.intern] = n != 'price' ? item.at(n).text : item.at(n).text.to_i 
              end 
      attachments_array = item.css('image_urls').map do |url| 
                 url.text.split(' ') 
                end.flatten 
      @product = self.products.create!(product_hash) 
      attachments_array.each do |p| 
       @product.attachments.create!(remote_picture_url: p) 
      end 
     end 
    end 
end 

открыть файл XML, и я разобрать его создания хэш с Proucts Params (product_hash). В то же время продукт может иметь одно или несколько вложений, заданных тегом image_urls. Я анализирую после этого тега для каждого продукта и создаю массив с URL-адресами изображений, которые есть у продукта. Я создаю продукт, и для каждого изображения создаю вложение.

Однако я хочу, чтобы создать вложения с помощью вложенных атрибутов, поэтому я добавил это в моей модели продукта:

accepts_nested_attributes_for :attachments 

И это в моем разрешенном Params в контроллере продукта (по другим признакам):

params.require(:product).permit(attachments_attributes: [:id, :product_id, :picture, :remote_picture_url]) 

Я попытался сделать хэш из attachments_array и слияния его с product_hash, таким образом, она должна создавать вложения вместе с продуктом, используя вложенные атрибуты:

attachments_array = item.css('image_urls').map do |url| 
        {remote_picture_url: url.text.split(' ') } 
        end.flatten 
@product = self.products.create!(product_hash.merge!({attachments_attributes: attachments_array})) 

Однако это явно не решение, так как я получаю:

NoMethodError: undefined method `gsub' for #<Array:0x007f3b6d832138> 

Мой вопрос, как я могу отправить массив вложенных атрибутов наряду с основным объектом будет создан?

ответ

1

Вы можете создавать вложения продуктов затем сохранить продукт

product = Product.new(product_hash) 
attachements_array.each do |url| 
    product.attachements.build(remote_picture_url: url) 
end 
product.save 

Если вы хотите включить все элементы в хеш, то ваш product хэш будет

product_hash = {product_attr1: product_attr1_val, product_attr2: product_attr2_val, attachementes_attributes: [{attach_attr1: attach_attr1_val}, {attach_attr1: attach_attr1_val}] } 
Product.create(product_hash) 

Подробнее об этом: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

+0

Так что я был не прав, и мне удалось выяснить, как вы заявили, что мой файл attachments_array имеет массив как атрибут в хэше. Я задам этот вопрос здесь, так как это может быть полезно. Тем более, когда вы дали четкий ответ на то, что вы должны отправить. –