如何用 Faker gem 填充 belongs_to 模型

how to populate belongs_to model with Faker gem

当前架构是这样的:

ActiveRecord::Schema.define(version: 20160622075955) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.string   "body"
    t.date     "date"
    t.integer  "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  add_index "posts", ["user_id"], name: "index_posts_on_user_id", using: :btree

  create_table "users", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  add_index "users", ["first_name"], name: "index_users_on_first_name", using: :btree
  add_index "users", ["last_name"], name: "index_users_on_last_name", using: :btree

  add_foreign_key "posts", "users"
end

尝试填充两个模型:Posts & Users

这就是我要 seeds.rb

20.times do |n| 
    a = User.new
    a.first_name = Faker::Name.first_name
    a.last_name = Faker::Name.last_name

    a.save

end

10.times do |n|
    b = Post.new
    b.title = Faker::Book.title
    b.body = Faker::Lorem.words(4, true)
    b.date = Faker::Time.between(DateTime.now - 1, DateTime.now) 

    b.save
end

它适用于 User 但不适用于 Post。我如何也填充 Post

编辑

Post的型号

class Post < ActiveRecord::Base
  belongs_to :user
  validates :title, :body, presence: true
  validates :title, length: { maximum: 40 }
end

用户模型

class User < ActiveRecord::Base
    has_many :posts
    validates :first_name, :last_name, presence: true
end

用户控制器

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save 
      flash[:notice] = "User successfully added!"
      redirect_to users_path
    else
      render :new
    end
  end

  def edit
    @user = User.find(params[:id])
    render :edit
  end

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      redirect_to users_path
    else
      render :edit
    end
  end

  def destroy
    @user = User.find(params[:id])
    @user.destroy
      redirect_to users_path
  end

  private 

    def user_params
      params.require(:user).permit(:first_name, :last_name)
    end

end

Post的控制器

class PostsController < ApplicationController

  def new 
    @user = User.find(params[:user_id])
    @post = @user.posts.new
  end

  def edit
    @user = User.find(params[:user_id])
    @post = @user.posts.find(params[:id])
    render :edit
  end

  def create 
    @user = User.find(params[:user_id])
    @post = @user.posts.new(post_params)
    if @post.save 
      redirect_to user_path(@post.user)
    else
      render :new
    end
  end

  def update 
    @user = User.find(params[:user_id])
    @post = @user.posts.find(params[:id])
    if @post.update(post_params)
      redirect_to user_path(@post.user)
    else
      render 'edit'
    end
  end


  def destroy
    @user = User.find(params[:user_id])
    @post = @user.posts.find(params[:id])
    @post.destroy
      redirect_to users_path
    end

  private 

  private 
    def post_params
      params.require(:post).permit(:title, :body, :date)
    end
end

编辑两个

当我将 puts b.errors.inspect 放入 seeds.rb 文件时没有出现错误。

然而,当我 运行 rake db:seed

#<ActiveModel::Errors:0x007fa20d45aec8 @base=#<Post id: 1, title: "Surprised by Joy", body: "[\"sunt\", \"audentia\", \"pectus\", \"omnis\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d463a28 @base=#<Post id: 2, title: "The Golden Bowl", body: "[\"cohibeo\", \"verus\", \"ut\", \"corrupti\"]", date: "2016-06-27", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d450220 @base=#<Post id: 3, title: "Such, Such Were the Joys", body: "[\"video\", \"tepesco\", \"stabilis\", \"esse\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d439d18 @base=#<Post id: 4, title: "Jesting Pilate", body: "[\"aut\", \"textor\", \"tui\", \"subiungo\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d428888 @base=#<Post id: 5, title: "Great Work of Time", body: "[\"cupiditas\", \"debeo\", \"decipio\", \"clementia\"]", date: "2016-06-27", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d4192c0 @base=#<Post id: 6, title: "Look to Windward", body: "[\"totidem\", \"numquam\", \"ut\", \"amita\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d409d70 @base=#<Post id: 7, title: "Vile Bodies", body: "[\"cruentus\", \"adiuvo\", \"stella\", \"cimentarius\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d3fa6e0 @base=#<Post id: 8, title: "Consider the Lilies", body: "[\"dolor\", \"sumptus\", \"solutio\", \"theologus\"]", date: "2016-06-27", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d3eaf38 @base=#<Post id: 9, title: "Terrible Swift Sword", body: "[\"aspernatur\", \"aegrus\", \"studio\", \"adstringo\"]", date: "2016-06-26", user_id: nil, created_at: "2016-06-28 04:38:02", updated_at: "2016-06-28 04:38:02">, @messages={}>
#<ActiveModel::Errors:0x007fa20d3db920 @base=#<Post id: nil, title: "By Grand Central Station I Sat Down and Wept", body: "[\"earum\", \"rerum\", \"defessus\", \"sed\"]", date: "2016-06-26", user_id: nil, created_at: nil, updated_at: nil>, @messages={:title=>["is too long (maximum is 40 characters)"]}>

错误是 Faker 有时创建的标题 大于 40 个字符 。 (看看上面的例子,你已经创建了 9 个 post(因为它们有一个 ID),只有一个失败了(最后有错误信息)

@messages={:title=>["is too long (maximum is 40 characters)"]}

如果你想用Faker,你可以砍标题

b.title = Faker::Book.title[0..40] 
# it will get only the first 40 characters

这样您将创建 20 个用户,每个用户 1 个 post。您可以添加另一个 5.times do ... end wrapping Post 创建,这样每个用户将有 5 个 post。你也可以只创建一个用户,然后设置所有 post.user = User.first,这样你就会有一个用户有很多 Posts.

20.times do
    user = User.new
    user.first_name = Faker::Name.first_name
    user.last_name = Faker::Name.last_name

    user.save

    post = Post.new
    post.title = Faker::Book.title[0..40]
    post.body = Faker::Lorem.words(4, true)
    post.date = Faker::Time.between(DateTime.now - 1, DateTime.now) 
    post.user = user
    post.save
end