Alexandr Dmitrenko
Alexandr Dmitrenko

Reputation: 153

Rails: Object creation with has_many / belongs_to association

There are two models Task and Project. A Project has many 'Task's and a 'Task' belongs_to a `Project'.

class Task < ActiveRecord::Base
  belongs_to :project
end

class Project < ActiveRecord::Base
  has_many :tasks
end

A list of all Tasks is displayed as a separate page for each Project and displays your Tasks.

How to create the condition for the method create, so that the Task be able to be created as an independent object, and associated with the Project?

My knowledge was only enough to write two separate methods.

To create associated objects:

def create
  @project = Project.find(params[:project_id])
  @task = @project.tasks.create(task_params)
  redirect_to project_path(@project)
end

To create a separate object:

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

  respond_to do |format|
    if @task.save
      format.html { redirect_to @task, notice: 'Task was successfully created.' }
      format.js {}
      format.json { render json: @task, status: :created, location: @task }
    else
      format.html { render action: "new" }
      format.json { render json: @task.errors, status: :unprocessable_entity }
    end
  end
end

How to do it one method?

Upvotes: 0

Views: 458

Answers (2)

Alexandr Dmitrenko
Alexandr Dmitrenko

Reputation: 153

Task Controller:

def index
  @tasks = Task.all
  @task  = Task.new
end

def create
 @task = if params[:project_id]
   @project = Project.find(params[:project_id])
   @project.tasks.build(task_params)
 else
   Task.new(task_params)
 end
 ...

Project Model:

class Project < ActiveRecord::Base
  has_many :tasks, dependent: :destroy
  accepts_nested_attributes_for :tasks,
                      :allow_destroy => true
end

and in projects controller

private      
def project_params
      params.require(:project).permit(:name, ....., taks_attributes: [:id, .....,:_destroy])
end

Upvotes: 0

froderik
froderik

Reputation: 4808

You have to pass in the project_id to your second method. Then you can add

@task.project_id = params[:project_id]

or something like that. If tasks always belongs to projects you may want to model them as a nested resource.

Upvotes: 1

Related Questions