McCauley
McCauley

Reputation: 15

(Ruby on Rails) Help to add Hash to DB

Ruby 2.0, Rails 4.1.0, sQlite3. I have to create params in Hash to add to my db. I have yaml file and model:

class User < ActiveRecord::Base
  has_many :tweets
  accepts_nested_attributes_for :tweets
end
class Tweet < ActiveRecord::Base
  belongs_to :user
end

I have 15 users. Try to run this code

UsTw_model_params = {user: []}

count_of_users = seeds_yml["users"].length - 1

for i in 0..count_of_users do 
  UsTw_model_params[:user][i] = {}
  UsTw_model_params[:user][i][:name] = seeds_yml["users"][i]["name"]
  UsTw_model_params[:user][i][:email] = seeds_yml["users"][i]["email"]
  UsTw_model_params[:user][i][:password] = seeds_yml["users"][i]["password"]
  UsTw_model_params[:user][i][:avatar] = seeds_yml["users"][i]["avatar"]
  UsTw_model_params[:user][i][:tweets_attributes] = []

  if seeds_yml["users"][i].has_key?(:tweets)
    count_of_tweets = seeds_yml["users"][i]["tweets"].length - 1
    for j in 0..count_of_tweets do
        UsTw_model_params[:user][i][:tweets_attributes][j] = {}
        UsTw_model_params[:user][i][:tweets_attributes][j][:post] = seeds_yml["users"][i]["tweets"][j]["post"]
        UsTw_model_params[:user][i][:tweets_attributes][j][:created_at] = seeds_yml["users"][i]["tweets"][j]["created_at"]
    end 
  end
end

User.create(UsTw_model_params[:user])

And get error ActiveRecord::UnknownAttributeError: unknown attribute: user

What's the matter?

Upvotes: 0

Views: 86

Answers (1)

max
max

Reputation: 102222

First of all anything starting with a capital letter in Ruby is treated as a constant. Reassigning a constant results in a warning. Specifically:

UsTw_model_params = {user: []} # is a constant!

Examples:

class User
module Huggable
TAU = 2 * PI

Variables should by convention be in snakecase such as:

user_tweet_params

Second, you can leave for loops behind. Ruby has far better methods to loop within arrays and other enumables such as map, each, etc.

# Loop though seeds_yml["users"] and create a new array
user_tweet_params = seeds_yml["users"].map do |user|
    # with_indifferent_access allows us to use symbols or strings as keys
    user = user.with_indifferent_access
    user.slice!(:name, :email, :password, :avatar, :tweets)

    # Does the user have tweets?
    # We use try(:any?) incase user["tweets"] is nil
    if user[:tweets].try(:any?)
        # Take the tweets and nest then under tweet_attributes
        user[:tweet_attributes] = user.tweets.map do |tweet|
            tweet.with_indifferent_access.slice!(:post, :created_at)
        end
    end

    # remove the original tweets
    user.delete(:tweets)
    # return user
    user
end

Upvotes: 1

Related Questions