Home Save current user with created object
Reply: 1

Save current user with created object

Max Heumann
1#
Max Heumann Published in 2018-02-14 10:27:29Z

I have a problem getting the current user to be saved with a created object in my rails app.

I followed the Michael Hartl rails tutorial until chapter 10 (I don't need the following functions of chapters 11 to 14.) Starting there I generated some scaffolds for children and kindergarten and edited the relations in the models (e.g. user has many children, child belongs to user). The aim is to get an app where the user can either create his or her child or children if the user is assigned a parents role, or the user can create a kindergarten if the user is assigned a kindergarten-manager role. Afterwards the app should help to allocate all the registered children to all the registered Kindergarten places.

My current Problem is that a user (no roles at this point, just regular user) can't create a child in the web interface because it says "user must exist" when trying to save a child, because i suppose no user is assigned to the child. Unfortunately i don't know how to save the current user to the child. I found a very similar question here and I tried to follow the answer but I was not able to fix the problem, instead I am now getting an error. I edited the .merge(user: current_user) part to the child controller but it gives me the error:

"ActiveModel::MissingAttributeError in ChildrenController#create can't write unknown attribute user_id"

    # POST /children.json
    def create
      @child = Child.new (child_params)
      @child.save

Models user.rb and child.rb:

    #app/models/child.rb
    class Child < ApplicationRecord
      belongs_to :user
      validates :user, presence: true
    end

    #app/models/user.rb
    class User < ApplicationRecord
      attr_accessor :remember_token, :activation_token, :reset_token
      has_many :children, dependent: :destroy
      has_many :kindergartens, dependent: :destroy
    ....
    end

children_controller.rb:

    #app/controllers/children_controller.rb
    class ChildrenController < ApplicationController
      before_action :set_child, only: [:show, :edit, :update, :destroy]

    ....

      def create
         @child = Child.new child_params
         @child.save

         respond_to do |format|
           if @child.save
            format.html { redirect_to @child, notice: 'Child was successfully created.' }
            format.json { render :show, status: :created, location: @child }
           else
            format.html { render :new }
            format.json { render json: @child.errors, status: :unprocessable_entity }
           end
         end
       end

    ....

       def child_params
         params.require(:child).permit(:firstname, :lastname, :postalcode, :city, :street, :addr_number, :gender, :disability, :allday, :halal, :koscher, :vegetarian, :vegan).merge(user: current_user)
       end
    end
fool-dev
2#
fool-dev Reply to 2018-02-14 12:51:08Z

At first you need add user_id index to the childrens table.

Then

If you have login & logout functionalities, I mean session is working currently then how you manage the user session? Something like this?

def current_user
  @current_user ||= User.find_by(id: session[:user_id])
end

If yes then go to create method and edit like below

@child = Child.new child_params
@child.user = current_user
@child.save

And remove this .merge(user: current_user) from child_params, it will work I hope.

If above solution does not work somehow then pass user_id manually with form like in the form

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

Then the user_id add to the strong parameters like others attributes.

You can see the test like while user_id passing properly then what's happening like

Just For Testing Purpose

@child = Child.new child_params
@child.user = User.last
@child.save

Part 2

If you need to give permission to the children_controller like if user has parent then he/she access to the children_controller form then create a method like this

before_action :require_parants, only: [:new, :create] # top of the controller
private
# parant column on the users table is boolean true/false
def require_parants
    if !logged_in? || (logged_in? and !current_user.parant?)
        flash[:danger] = "Only parants can create child"
        redirect_to root_url
    end
end

The logged_in? based on this

# Returns true if the user is logged in, false otherwise.
def logged_in?
  !current_user.nil?
end

then redirect to the root URL when the user is not a parent.

Hope it helps

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.354047 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO