简体   繁体   English

Rails csv导入与关联

[英]Rails csv import with associations

I am building a rails application that associates posts with many different categories. 我正在构建一个rails应用程序,它将帖子与许多不同类别相关联。 For example, I have a Post and need to be able to assign it to the categories Sports, News and Science through csv import via rake task. 例如,我有一个帖子,需要能够通过rake任务通过csv导入将它分配到体育,新闻和科学类别。

My question is how can I import an array of multiple category_ids into my Post model? 我的问题是如何将多个category_ids数组导入到Post模型中? I have it working where I can manually create a new Post and assign multiple categories to the post, but I am confused as to how to complete this through csv. 我有它的工作,我可以手动创建一个新的帖子,并为帖子分配多个类别,但我很困惑如何通过csv完成这一点。 I need help figuring out the best way to accomplish this. 我需要帮助找出实现这一目标的最佳方法。

Here is what I have so far: 这是我到目前为止:

Schema 架构

  create_table "posts", force: :cascade do |t|
    t.string   "name"
    t.text     "description"
  end

  create_table "styles", force: :cascade do |t|
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.integer  "post_id"
    t.integer  "category_id"
  end

  create_table "categories", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at",        null: false
    t.datetime "updated_at",        null: false
  end

Post.rb Post.rb

class Post < ApplicationRecord  
  has_many :styles
  has_many :categories, through: :styles
end

Category.rb Category.rb

class Category < ApplicationRecord
  has_many :styles
  has_many :posts, through: :styles
end

Style.rb Style.rb

class Style < ApplicationRecord
  belongs_to :post
  belongs_to :category
end

Rake Task 耙任务

require 'csv'
require 'open-uri'
namespace :post_import do
  desc "Import posts daily"
  task posts: :environment do
    filename = File.join Rails.root, "posts.csv"
    counter = 0

    CSV.foreach(filename) do |row|
      name, category, description = row
      post = Post.create(name: name, category_ids: category, description: description)
      counter += 1 if post.persisted?
    end

    puts "Imported #{counter} [posts]"
  end
end
require 'csv'
require 'open-uri'
namespace :post_import do
  desc "Import posts daily"
  task posts: :environment do
    filename = File.join Rails.root, "posts.csv"
    counter = 0

    CSV.foreach(filename) do |row|
      name, category, description = row

      #you can user find or create, but for clarity I split it
      post = Post.where(name: name).first
      post = Post.new(name: name, description: description) if post == nil

      #now we can simply add the style which joins to the category
      post.styles.build(category_id: category)
      post.save
      counter += 1 if post.persisted?
    end

    puts "Imported #{counter} [posts]"
  end
end

I was able to solve this with help from Chris at gorails.com. 我能够在gorails.com的Chris的帮助下解决这个问题。 Here is my (rough) working solution. 这是我的(粗略)工作解决方案。 Hope this helps anyone else with this issue! 希望这可以帮助其他人解决这个问题!

require 'csv'
require 'open-uri'
namespace :post_import do
  desc "Import posts daily"
  task posts: :environment do
    filename = File.join Rails.root, "posts.csv"
    counter = 0

    CSV.foreach(filename) do |row|
      name, category_ids, description = row
      post = Post.new(name: name, description: description) if post == nil
      post.save 

      #separate string of category ids into array
      a_categories = category_ids.split(",")

      a_categories.each do |category_id|
        post.styles.where(category_id: category_id).first_or_create
      end

      counter += 1 if post.persisted?
    end

    puts "Imported #{counter} [posts]
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM