There is a user who can create tasks and projects. Tasks can be either an independent unit or belong to a project. Therefore, you must be able to create tasks on the page of an existing project.

Models

class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_many :projects has_many :tasks end class Task < ActiveRecord::Base include RankedModel ranks :row_order belongs_to :user belongs_to :project end class Project < ActiveRecord::Base belongs_to :user has_many :tasks accepts_nested_attributes_for :tasks, allow_destroy: true end 

Project Controller

  def show @project = Project.find(params[:id]) @project.tasks.build end def create @project = current_user.projects.new(project_params) respond_to do |format| if @project.save format.html { redirect_to @project, notice: 'Project was successfully created.' } format.js {} format.json { render json: @project, status: :created, location: @project } else format.html { render action: "new" } format.json { render json: @project.errors, status: :unprocessable_entity } end end end .... private def project_params params.require(:project).permit(:name) end end 

Task Controller

 before_filter :authenticate_user! def after_sign_in_path_for(resource) request.env['omniauth.origin'] || stored_location_for(resource) || root_path end def after_sign_out_path_for(resource_or_scope) request.referrer end def index @tasks = current_user.tasks.rank(:row_order).all @task = current_user.tasks.new @projects = current_user.projects.all @project = current_user.projects.new end def update_row_order @task = Task.find(task_params[:task_id]) @task.row_order_position = task_params[:row_order_position] @task.save render nothing: true end 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 ...... private def task_params params.require(:task).permit(:task_id, :name, :row_order_position) end 

For the page of the existing project made the following view :

url: / projects / 1

  <table> <% @project.tasks.each do |task| %> <tr> <td><%= task.name %></td> </tr> <% end %> </table> <%=form_for([@project, @project.tasks.build]) do |f| %> <div class="input-group"> <div aria-describedby="add_task"> <%=f .text_field :name, class: 'form-control ' %> </div> <span class="input-group-btn"> <%= f.submit 'Добавить', class: 'btn btn-success btn-secondary', id: "add_task" %> </span> </div> <% end %> 

Can you please tell me how to create a task associated with a specific project via the show method?

And in addition fields from db:

 create_table "projects", force: :cascade do |t| t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "user_id" end create_table "tasks", force: :cascade do |t| t.string "name" t.string "status" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "row_order" t.integer "user_id" t.integer "project_id" end 
  • Can you please tell me correctly, did I make associations? And how to create a task in the controller in the controller so that it belongs to a specific project and was visible only to an authorized user - @tasks = current_user.projects.tasks.new ? - Alexandr Dmitrenko
  • Edited and updated the question. Please tell me which direction to look for a mistake - I don’t understand where the problem may be, in the controller or I’m just doing something wrong in view - Alexandr Dmitrenko
  • show in the controller looks extremely suspicious. - D-side
  • Agree
  • one
    I would in your situation arm myself with a crowbar and uncover the place where this name is displayed in order to see what is in the task . I suggest starting here :) - D-side

1 answer 1

The projects#show method is completely projects#show here, in fact. The form, in theory, can be displayed anywhere, would be a project.

It is important to prepare another: a destination for data from the form.

Presentation - › route -› controller - ›model.

Route

Rails strongly encourages the use of resources in routes. If the resources :projects are already there, then the route for creating new tasks can be added as follows:

 resources :projects do # Это уже должно быть resources :tasks, only: [:create] end 

It turns out POST /projects/:project_id/tasks .

Controller

A typical “resource inside a scopa” pattern: with the help of before_action controller receives a “place of action” (in this case, the tasks of a separate project) and then tries to accomplish what is said in this “place of action”

 class TasksController < ApplicationController before_action do @project = Project.find(params[:project_id]) end def create @project.tasks.create(project_params) end def project_params params.require(:task).permit(:не, :знаю, :что, :тут, :у, :вас) end end 

Three one-liners. Approximately to such simplicity of controlers in Rails also aspire, therefore and are not afraid to make a separate case, even if in it only one method is necessary.

  • Updated data on their controllers and view . When inserting the code you specified before_action do @project = Project.find(params[:project_id]) end error occurs: screenshot - Alexandr Dmitrenko
  • @AlexandrDmitrenko if you have something else in the controller, you will have to adapt the above code. I cannot be responsible for any changes made by a specific project. In this case, most likely, it will be enough to specify before_action 'for specific actions, but you have too much dumped in this controller. - D-side