Search code examples
ruby-on-railsactiverecordruby-on-rails-4associationsrails-postgresql

My user id isn't saving


My user id isn't saving and I do not understand why. I added the associations to both models and added the user_id to the notification params but the user id does not save automatically.

The campus_id relation does work properly and I do not really see the difference. What could be the problem? I am using a postgress database.

rails server log

  Rendered /usr/local/rvm/gems/ruby-2.1.1@rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (59.4ms)




Started POST "/campus/1/notifications" for 84.193.153.106 at 2014-10-18 19:41:03 +0000
Started POST "/campus/1/notifications" for 84.193.153.106 at 2014-10-18 19:41:03 +0000
Processing by NotificationsController#create as HTML
Processing by NotificationsController#create as HTML
  Parameters: {"utf8"=>"_", "authenticity_token"=>"L9RH3hZyAKqzq9/kuJJDNaEHNVca2DbQSKSZLc8iTuw=", "notification"=>{"post"=>"thisisatest"}, "commit"=>"Maak notificatie", "campu_id"=>"1"}
  Parameters: {"utf8"=>"_", "authenticity_token"=>"L9RH3hZyAKqzq9/kuJJDNaEHNVca2DbQSKSZLc8iTuw=", "notification"=>{"post"=>"thisisatest"}, "commit"=>"Maak notificatie", "campu_id"=>"1"}
  Campus Load (0.6ms)  SELECT "campus".* FROM "campus" WHERE "campus"."id" = $1 LIMIT 1  [["id", "1"]]
  Campus Load (0.6ms)  SELECT "campus".* FROM "campus" WHERE "campus"."id" = $1 LIMIT 1  [["id", "1"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
   (0.2ms)  BEGIN
   (0.2ms)  BEGIN
  SQL (134.0ms)  INSERT INTO "notifications" ("campus_id", "created_at", "post", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["campus_id", 1], ["created_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00], ["post", "thisisatest"], ["updated_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00]]
  SQL (134.0ms)  INSERT INTO "notifications" ("campus_id", "created_at", "post", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["campus_id", 1], ["created_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00], ["post", "thisisatest"], ["updated_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00]]
   (42.1ms)  COMMIT
   (42.1ms)  COMMIT
Redirected to https://sl-backoffice-c9-christoph88.c9.io/notifications/9
Redirected to https://sl-backoffice-c9-christoph88.c9.io/notifications/9
Completed 302 Found in 188ms (ActiveRecord: 177.4ms)
Completed 302 Found in 188ms (ActiveRecord: 177.4ms)

Notification model

class Notification < ActiveRecord::Base
  belongs_to :campus
  belongs_to :user

  validates :post, presence: true
  validates :campus_id, presence: true
end

User model

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable

  has_many :notifications
  has_many :spotlights
end

notifications controller

class NotificationsController < ApplicationController
  before_action :set_notification, only: [:show, :edit, :update, :destroy]
  before_action :set_campus, only: [:index, :new, :create]
  before_action :authenticate_user!

  def index
    @notifications = @campus.notifications
  end

  def show
    @campus = @notification.campus
  end

  def new
    @notification = @campus.notifications.build
  end

  def edit
  end

  def create
    @notification = @campus.notifications.build(notification_params)

    respond_to do |format|
      if @notification.save
        format.html { redirect_to @notification }
        format.json { render action: 'show', status: :created, location: @notification }
        flash[:success] = 'Notification was successfully created.' 
      else
        format.html { render action: 'new' }
        format.json { render json: @notification.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @notification.update(notification_params)
        format.html { redirect_to @notification }
        format.json { head :no_content }
        flash[:success] = 'Notification was successfully updated.' 
      else
        format.html { render action: 'edit' }
        format.json { render json: @notification.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @notification.destroy
    respond_to do |format|
      format.html { redirect_to campu_notifications_url(@notification.campus_id) }
      format.json { head :no_content }
      flash[:error] = 'Notification was successfully deleted.' 
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_notification
      @notification = Notification.find(params[:id])
    end

    def set_campus
      @campus = Campus.find(params[:campu_id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def notification_params
      params.require(:notification).permit(:post, :campus_id, :user_id)
    end
end

schema.rb

# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

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

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

  create_table "campus", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "collis", force: true do |t|
    t.string   "name"
    t.text     "teaser"
    t.text     "description"
    t.string   "coursetype"
    t.text     "target"
    t.string   "campus"
    t.datetime "startdate"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "guid"
  end

  create_table "coursespotlights", force: true do |t|
    t.boolean  "spotlight"
    t.integer  "colli_id"
    t.datetime "start"
    t.datetime "stop"
    t.string   "colli_guid"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "coursespotlights", ["colli_id"], name: "index_coursespotlights_on_colli_id", using: :btree

  create_table "notifications", force: true do |t|
    t.text     "post"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "campus_id"
    t.integer  "user_id"
  end

  add_index "notifications", ["campus_id"], name: "index_notifications_on_campus_id", using: :btree
  add_index "notifications", ["user_id"], name: "index_notifications_on_user_id", using: :btree

  create_table "spotlights", force: true do |t|
    t.boolean  "spotlight"
    t.datetime "start"
    t.datetime "stop"
    t.string   "name"
    t.text     "teaser"
    t.datetime "coursedate"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "campus_id"
    t.integer  "user_id"
  end

  add_index "spotlights", ["user_id"], name: "index_spotlights_on_user_id", using: :btree

  create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.string   "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.string   "unconfirmed_email"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

end

Solution

  • Because user_id is not a part of your parameters

    From the log:

    Parameters: {"utf8"=>"_", "authenticity_token"=>"L9RH3hZyAKqzq9/kuJJDNaEHNVca2DbQSKSZLc8iTuw=", "notification"=>{"post"=>"thisisatest"}, "commit"=>"Maak notificatie", "campu_id"=>"1"}
    

    then the line from the strong params filters out unwanted content

    params.require(:notification).permit(:post, :campus_id, :user_id)
    

    this means only "notification"=>{"post"=>"thisisatest"} part will be allowed

    then from the sql insert:

    SQL (134.0ms)  INSERT INTO "notifications" ("campus_id", "created_at", "post", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["campus_id", 1], ["created_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00], ["post", "thisisatest"], ["updated_at", Sat, 18 Oct 2014 19:41:03 UTC +00:00]]
    

    you have campus_id here because you are doing the update on @campus:

    @campus.notifications.build(notification_params)
    

    so, just make sure user_id comes in as part of notification and that is it!