Ryan Blakely

Joined

140 Experience
0 Lessons Completed
0 Questions Solved

Activity

Posted in Rails csv import with associations

Thanks so much for the help Chris. I'm going to spend some time reviewing all of this but I was able to get it to work with the final code bit you shared.

Here is my current (now working) rake file for those also looking for the solution :

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

Posted in Rails csv import with associations

I am able to split the ids into an array successfully - but somewhere in

categories = Category.where(id: category_ids)
post.categories = categories

the output becomes quadruplicated and I dont understand why. I am using a csv with only one row of data for testing. Even when I remove multiple category ids and leave a single id, the output of post.categories is [1,1,1,1]. I dont think this is what you mean by idemoptent as this is a single csv imported once.

here is the code that I am using for my rake due to my particular schema:

a_categories = category_ids.split(",")
categories = Style.where(category_id: a_categories)
post.styles = categories

Is there anything here that could cause the quadruplication?

Posted in Rails csv import with associations

Thanks Chris, I have the join table created though my naming convention is not the most logical - I've called it styles rather than PostCategories.

My csv formats the categories by ID. For example a row would look like "1,2,3" with 1, 2, 3 representing the category_ids of three unique categories. Can you give me an example of how to split them up and "do a Category.find() on them to grab the categories"?

Here is what I have in my 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, description: description)
      post.styles.build(category_id: category)

      counter += 1 if post.persisted?
    end

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

This works, but only for the first category in the row. Categories 2 and 3 arent being assigned.

Posted in Hi, my name is...

Thanks Nick and Andrew! I've been using the videos for a little while but excited to participate in the community now!
Andrew - I'm running a half-marathon in February as well! (Phoenix marathon). Best of luck with your training! I plan on starting a fairly light 12 week training program just after thanksgiving, let me know if you'd like me to send you a copy!

Posted in Rails csv import with associations

I am building a rails application that associates posts with many different categories. 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.

My question is how can I import an array of multiple category_ids into my Post model? 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. 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

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

Category.rb

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

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

Posted in Hi, my name is...

Ryan Blakely. I'm a PHX, Arizona based Rails developer. I started learning Rails about 2 years ago during my senior year of college at Arizona State University. After graduating and working for a year as an Industrial Engineer, I decided to leave my job to focus on coding full time. I started a web development shop called Open-Labs and build sites for local clients to pay the bills. In my free time I make tutorials on how to build rails apps and share what I am learning on my youtube channel. A few side projects I am currently working on include Vihbe and Open-Rails.

When I'm not coding I enjoy traveling, hiking, running, photography, art and yoga.

I'm excited to be a part of this great community Chris has created and hope to meet others like me. Please feel free to say hello!

logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2020 GoRails, LLC. All rights reserved.