T. Bo
T. Bo

Reputation: 3

How to create an object automatically after initialising object?

I have a Task and a Tick. After the user creates a Task, I want to automatically create a Tick.

  def create
      @task = current_user.tasks.build(task_params)

      @task.category_id = params[:category_id]

      respond_to do |format|
          if @task.save
              format.html { redirect_to tasks_path, notice: 'Task was successfully created.' }

            # @task.ticks.build(user_id: @user, complete: false) # doesn't create tick, but shows no error
            # Tick.create(user_id: @user.id, tick_id: @tick.id, complete: false) #error: undefined method `id' for nil:NilClass
          else
              format.html { render :new }
          end
     end
  end 

Tick model:

class Tick < ApplicationRecord
   belongs_to :task
   belongs_to :user
end

Task model

class Task < ApplicationRecord
    belongs_to :user
    belongs_to :category
    has_many :ticks
end

I've tried all the answers from this similar question:

This, on the line above respond_to do |format|

@task.ticks.build(user_id: @user, complete: false) 

(which throws NoMethodError in Tasks#create ... undefined method `map' for nil:NilClass)


I've these after if @task.save

@task.ticks.build(user_id: @user, complete: false)

(doesn't create tick, but shows no error)

Tick.create(user_id: @user.id, tick_id: @tick.id, complete: false) 

(Throws error: undefined method `id' for nil:NilClass)


Also, is there a technical name for what I'm trying to do?

Upvotes: 0

Views: 64

Answers (2)

Darpan Chhatravala
Darpan Chhatravala

Reputation: 520

Modify your create action as per below, you does not need to build class object, just initialise your class object with current user reference.

    def create
      @task = current_user.tasks.new(task_params)

      @task.category_id = params[:category_id]

      respond_to do |format|
          if @task.save
              format.html { redirect_to tasks_path, notice: 'Task was successfully created.' }

            # @task.ticks.build(user_id: @user, complete: false) # doesn't create tick, but shows no error
            # Tick.create(user_id: @user.id, tick_id: @tick.id, complete: false) #error: undefined method `id' for nil:NilClass
          else
              format.html { render :new }
          end
     end
  end

here, you does not need to assign user_id to your object.

Upvotes: 0

rebagliatte
rebagliatte

Reputation: 2146

You can achieve this with a model callback

class Task < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  has_many :ticks

  after_create :set_tick

  private

  def set_tick
    self.ticks.create!(user: self.user, complete: false)
  end
end

Upvotes: 1

Related Questions