【问题标题】:How do I update a child db table when populating database in ruby on ralls?在 ruby​​ on rails 中填充数据库时如何更新子数据库表?
【发布时间】:2012-01-23 13:09:36
【问题描述】:

我的数据库中有以下表格:

  • 用户 - 有一个个人资料,有多个相册
  • 个人资料 - 属于用户
  • PhotoAlbum(s) - 属于用户,有很多照片
  • 照片 - 属于 PhotoAlbum

Faker 在填充我的用户表时工作正常,但我现在也希望更新我的配置文件表,但它根本不起作用。数据库中的行仍然是空的。运行 rake db:populate 时没有出现任何错误。

我是否遗漏了什么,请帮我看看哪里出了问题,并帮助我想出一个解决方案,因为当我需要填充其他表格时,这也会对我有所帮助。我从这个答案中学到的东西可以帮助我完成我即将完成的其他任务。

libs/task/sample_data.rake

   namespace :db do
        desc "Create user records in the development database."
        task :populate => :environment do
          require 'faker'


          def randomDate(params={})
            years_back = params[:year_range] || 5
            latest_year  = params [:year_latest] || 0
            year = (rand * (years_back)).ceil + (Time.now.year - latest_year - years_back)
            month = (rand * 12).ceil
            day = (rand * 31).ceil
            series = [date = Time.local(year, month, day)]
            if params[:series]
              params[:series].each do |some_time_after|
                series << series.last + (rand * some_time_after).ceil
              end
              return series
            end
            date
          end

          def decimal_selection_array(start,limit,step_size=1)
            decimal_array = (start..limit).step(step_size).map{|i| i.to_s}.to_a
            decimal_array.insert(0,"Below #{start.to_f}")
            decimal_array.insert(-1,"Above #{limit.to_f}")
          end

          100.times do |n|
            username = "#{Faker::Name.first_name}#{n}"
            u = User.create!(
              :username => username,
              :email => Faker::Internet.email,
              :password => "foobar"
            )


            u.profile.update_attributes(
          :motd                => Faker::Lorem.words,

          #Profile details
          :first_name          => Faker::Name.first_name,
          :last_name           => Faker::Name.last_name,
          :birthday            => randomDate(:year_range => 60, :year_latest => 22),     
          :gender              => (1..2).to_a.sample,
          :marital_status      => (1..7).to_a.sample,
          :sexual_preference   => (1..3).to_a.sample,
          :ethnicity           => (1..10).to_a.sample,
          :country             => Faker::Address.country,
          :location            => Faker::Address.country,

          #About the user
          :about_me            => Faker::Lorem.paragraph,

          #Personal stats
          :height              => decimal_selection_array(5.0,7.0,0.1).to_a.sample,
          :body_type           => (1..7).to_a.sample,
          :eye_colour          => (1..6).to_a.sample,
          :drugs               => (1..4).to_a.sample,
          :alcohol             => (1..4).to_a.sample,
          :cigarettes          => (1..3).to_a.sample,
          :likes               => Faker::Lorem.sentence,
          :dislikes            => Faker::Lorem.sentence,
          :bad_habits          => Faker::Lorem.sentence,

          #Favourite things
          :food                => Faker::Lorem.sentence,
          :music               => Faker::Lorem.sentence,
          :television          => Faker::Lorem.sentence,
          :book                => Faker::Lorem.sentence,
          :animal              => Faker::Lorem.sentence,
          :place               => Faker::Lorem.sentence,
          :possesion           => Faker::Lorem.sentence


            )





        end
      end
    end

亲切的问候

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1 rubygems


    【解决方案1】:

    调用 u.profile.update_attributes(params) 时,用户配置文件 (u.profile) 不存在。 你应该打电话给u.create_profile(params)

    使用nested attributes 也会有所帮助。

    【讨论】:

    • 这将为用户创建一个配置文件行,两倍于用户注册时自动创建的 1。
    • 好的,用户不仅是自动生成的,还可以注册?或者是通过钩子创建的配置文件,例如after_create :create_profile?请解释一下。
    • before_create :build_profile 是我的用户表的 User.rb 文件。当用户注册时,他们的个人资料的行也会自动创建。将用户表中的 ID 存储在配置文件表的 user_id 列中。
    • 这在问题中并不明显。您是否尝试过手动(通过控制台)创建单个用户/个人资料?
    • 并使用伪造的数据更新配置文件?可能是该数据无效?
    【解决方案2】:

    我通过以下方式解决了这个问题:

    注释掉:

    before_safe :build_profile 
    

    在我的用户模型中

    我将我的 rake 任务编辑为如下所示:

    # before running this task comment out: before_create :build_profile in user.rb in order to make this work correctly
    
    namespace :db do
        desc "Create user records in the development database."
        task :populate => :environment do
          require 'faker'
    
    
          def randomDate
            "#{(1900..2012).to_a.sample}-#{(1..12).to_a.sample}-#{(1..28).to_a.sample}"
          end
    
          def decimal_selection_array(start,limit,step_size=1)
            decimal_array = (start..limit).step(step_size).map{|i| i.to_s}.to_a
            decimal_array.insert(0,"Below #{start.to_f}")
            decimal_array.insert(-1,"Above #{limit.to_f}")
          end
    
          1000.times do |n|
            username = "#{Faker::Name.first_name}#{n+1}"
            User.create!(
              :username => username.gsub(/[^0-9a-z]/i, ''),
              :email => Faker::Internet.email,
              :password => "foobar"
            )
    
            Profile.create!(
          :user_id             => "#{n+1}",
          :motd                => Faker::Lorem.sentence,
    
          #Profile details
          :first_name          => Faker::Name.first_name.gsub(/[^a-z]/i, ''),
          :last_name           => Faker::Name.last_name.gsub(/[^a-z]/i, ''),
          :birthday            => randomDate,     
          :gender              => (1..2).to_a.sample,
          :marital_status      => (1..7).to_a.sample,
          :sexual_preference   => (1..3).to_a.sample,
          :ethnicity           => (1..10).to_a.sample,
          :country             => Faker::Address.country,
          :location            => Faker::Address.country,
    
          #About the user
          :about_me            => Faker::Lorem.paragraph,
    
          #Personal stats
          :height              => decimal_selection_array(5.0,7.0,0.1).to_a.sample,
          :body_type           => (1..7).to_a.sample,
          :hair                => (1..7).to_a.sample,
          :eye_colour          => (1..6).to_a.sample,
          :drugs               => (1..4).to_a.sample,
          :alcohol             => (1..4).to_a.sample,
          :cigarettes          => (1..3).to_a.sample,
          :likes               => Faker::Lorem.sentence,
          :dislikes            => Faker::Lorem.sentence,
          :bad_habits          => Faker::Lorem.sentence,
    
          #Favourite things
          :food                => Faker::Lorem.sentence,
          :sport               => Faker::Lorem.sentence,
          :music               => Faker::Lorem.sentence,
          :television          => Faker::Lorem.sentence,
          :book                => Faker::Lorem.sentence,
          :animal              => Faker::Lorem.sentence,
          :place               => Faker::Lorem.sentence,
          :possession          => Faker::Lorem.sentence
    
    
            )
    
    
        end
      end
    end
    

    由于验证失败,我不得不对 Faker 传入我的数据库的内容进行一些调整。诸如带有字母和数字以外的字符的用户名之类的事情,last_name 也发生了这种情况。所以我不得不过滤掉所有这些东西,然后我运行了拍摄任务并成功地更新了我的数据库,其中包含 1000 个用户的个人资料信息。

    只要我想添加示例数据以停止在创建时为用户创建配置文件行,我只需取消对 before_create 的注释。

    我还在我的 Profile 模型中将 user_id 添加到 attr_accessible,以便 user_id 列可以填充数字 1 到 1000,从而将它们与用户匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多