как заполнить модель own_to драгоценным камнем Faker

Текущая схема такова:

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

Попытка заполнить обе модели: сообщения и пользователи

Это то, что у меня есть для 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?

ИЗМЕНИТЬ

Модель публикации

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

Контроллеры почты

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)"]}>

person user273072545345    schedule 28.06.2016    source источник
comment
Не работает? Какие-то ошибки и т.д.?   -  person Ho Man    schedule 28.06.2016
comment
Имеет ли Post проверку для пользователя? после b.save добавьте puts b.errors.inspect и обновите свой вопрос с результатом. (Также вам не нужна переменная |n|, так как вы ее не используете)   -  person dpedoneze    schedule 28.06.2016
comment
Вы случайно не вызывали attr_accessor для атрибутов модели в модели Post?   -  person Petr Gazarov    schedule 28.06.2016
comment
@HoMan, нет, ошибок нет. просто не заполняется.   -  person user273072545345    schedule 28.06.2016
comment
@PetrGazarov, это рельсы 4, поэтому он не использует attr_accessor, but in the controller it does have it set in post_params`   -  person user273072545345    schedule 28.06.2016
comment
@dpedoneze, только что обновил вопрос выше с моделью сообщения. как видите, у него есть валидации   -  person user273072545345    schedule 28.06.2016
comment
Rails 4 по-прежнему использует attr_accessor к сведению.   -  person Petr Gazarov    schedule 28.06.2016
comment
@PetrGazarov, о, хорошо, спасибо! извините за непонимание с моей стороны. думал, что, поскольку у него есть post_params, в attr_accessor нет необходимости.   -  person user273072545345    schedule 28.06.2016
comment
@dpedoneze, обновил seeds.rb на puts b.errors.inspect... ошибок не возникло.   -  person user273072545345    schedule 28.06.2016
comment
Вы правы, это не так :). Если поставите, то у вас будут проблемы с сохранением модели, отсюда и мой вопрос.   -  person Petr Gazarov    schedule 28.06.2016
comment
сразу после b.save (и перед end) вы добавили puts b.errors.inspect, и это не показало никакой ошибки?!   -  person dpedoneze    schedule 28.06.2016
comment
Как вы проверяете, была ли запись создана?   -  person oreoluwa    schedule 28.06.2016
comment
@dpedoneze, не на локальной странице ... но я наконец понял, что он отображается в терминале, на который я не обратил внимания ... позвольте мне вставить его в вопрос выше   -  person user273072545345    schedule 28.06.2016
comment
Да, puts печатает на терминал. Поскольку вы используете seeds.rb, вам не нужен код контроллера   -  person dpedoneze    schedule 28.06.2016
comment
@dpedoneze, только что вставил выше.   -  person user273072545345    schedule 28.06.2016
comment
Хорошо, ошибка в том, что Faker иногда создают заголовки, длина которых превышает 40 символов. (посмотрите, что в приведенном выше примере вы создали 9 сообщений (потому что у них есть идентификатор) и только одно не удалось (с сообщением об ошибке в конце)   -  person dpedoneze    schedule 28.06.2016
comment
@ user27307254534534534543675765 Я разместил ответ на ваш вопрос   -  person dpedoneze    schedule 28.06.2016


Ответы (1)


Ошибка заключается в том, что Faker иногда создаются заголовки длиннее 40 символов. (посмотрите, что в приведенном выше примере вы создали 9 сообщений (потому что у них есть идентификатор) и только одно не удалось (с сообщением об ошибке в конце)

@messages={:title=>["слишком длинное (максимум 40 символов)"]}

Если вы хотите использовать Faker, вы можете вырезать заголовок.

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

Таким образом вы создадите 20 пользователей с 1 постом для каждого. Вы можете добавить еще 5.times do... завершить создание сообщения, чтобы у вас было 5 сообщений для каждого пользователя. Вы также можете создать только одного пользователя, а затем установить все post.user = User.first, так что у вас будет один пользователь с большим количеством сообщений.

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
person dpedoneze    schedule 28.06.2016
comment
хм, не уверен, что происходит ... но я вырезал заголовок в соответствии с вашим ответом ... и, да, в терминале не появляется никаких ошибок ... но также и сообщения не создаются. Только пользователи по-прежнему создаются. Верен ли мой файл seed.rb? - person user273072545345; 28.06.2016
comment
Как вы проверяете, создаются ли сообщения? попробуй открыть консоль rails c, набрать Post.count и потом снова запустить грабли. Затем снова проверьте Post.count и посмотрите, изменилось ли число. Я на 100% уверен, что они создаются, так как у них есть атрибуты id и created_at со значениями :) - person dpedoneze; 28.06.2016
comment
Поскольку вы не устанавливаете пользователя для созданных сообщений, вы не сможете связаться с ними, вызвав @user.post (или любой другой метод user.method), поскольку сообщения являются сиротами. - person dpedoneze; 28.06.2016
comment
чтобы ответить на ваш первый комментарий, я зашел в консоль rails и сделал подсчет сообщений. Получилось 10. Сделал грабли еще раз. Перезагрузил консоль. На этот раз получилось 20. Так что очевидно, что они создаются. Согласно вашему второму комментарию, как мне это исправить? Значит, я неправильно написал seeds.rb, да? Как написать так, чтобы посты создавались вместе с пользователями? - person user273072545345; 28.06.2016
comment
Вы можете установить пользователя, выполнив b.user = User.first, или вы можете создать нового пользователя для каждого сообщения. Это будет зависеть от того, как вам нужны начальные данные. - person dpedoneze; 28.06.2016