Когда я добавляю has_many, некоторые данные случайно не сохраняются

У меня есть 3 модели, Challenge, Pun, User (управляемый драгоценным камнем Clearance)

Пользователь может создать вызов. Вызов содержит много каламбуров. Пользователь также может создать Пан.

Все в порядке, пока я не установил Pun для принадлежащего пользователю, и вдруг Puns больше не сохраняются.

class User < ApplicationRecord
  include Clearance::User
  has_many :challenges
  has_many :puns
end

class Challenge < ApplicationRecord
  has_many :puns, :dependent => :delete_all
  belongs_to :user
end

class Pun < ApplicationRecord
  belongs_to :challenge
  belongs_to :user
end

В моем PunController я попытался установить идентификатор current_user

  def create
    @pun = @challenge.puns.create(pun_params)
    @pun.user_id = current_user.id if current_user
    redirect_to @challenge
  end

  private

  def set_challenge
    @challenge = Challenge.find(params[:challenge_id])
  end

  def pun_params
    params[:pun].permit(:pun_text,:user_id)
  end

Что я делаю неправильно? Я пытаюсь сделать это как можно более простым, но кажется, что пользователи не хотят ассоциироваться с более чем одной вещью, особенно если они вложенные. Это проблема оформления?

Настройка БД:

  create_table "challenges", force: :cascade do |t|
    t.text "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.datetime "start_time"
    t.datetime "end_time"
    t.bigint "user_id"
    t.index ["user_id"], name: "index_challenges_on_user_id"
  end

  create_table "puns", force: :cascade do |t|
    t.text "pun_text"
    t.bigint "challenge_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "user_id"
    t.index ["challenge_id"], name: "index_puns_on_challenge_id"
    t.index ["user_id"], name: "index_puns_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.string "tagline"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "encrypted_password", limit: 128
    t.string "confirmation_token", limit: 128
    t.string "remember_token", limit: 128
    t.index ["email"], name: "index_users_on_email"
    t.index ["remember_token"], name: "index_users_on_remember_token"
  end

2 ответа

Решение

Ну, в вашем текущем коде вы не сохраняете user_id после его установки. И если вы не ожидаете, что создание потерпит неудачу, вы можете сделать "создать!". Так что вы можете попробовать:

def create
  @challenge.puns.create!(pun_params.merge(user_id: current_user.id))

  redirect_to @challenge
end

Вы можете сделать это, используя просто hidden_field как в форме

<%= object.hidden_field :user_id, value: current_user.id %>

он не будет работать без сеанса пользователя, потому что отношения не являются обязательными, и удалите эту строку из контроллера

@pun.user_id = current_user.id if current_user

и перенаправить

redirect_to @pun

это будет работать

Другие вопросы по тегам