使用has_many创建记录:relationship

时间:2018-01-18 02:45:23

标签: ruby-on-rails

我在使用Rails中的has_many through:relationship创建记录时遇到问题。我有一个用户模型,一个任务模型和一个计时器模型。我们的想法是,用户has_many :taskshas_many :timers through: :tasks任务也有很多计时器。这个想法是,用户可以根据自己的需要创建任意数量的任务,并且每天自己定时执行特定任务以跟踪一段时间内的进度。

User.rb

class User < ApplicationRecord

  has_many :tasks
  has_many :timers, through: :tasks

end

Task.rb

class Task < ApplicationRecord
  validates :user_id, presence: true
  belongs_to :user
  has_many :timers 


end

Timer.rb

class Timer < ApplicationRecord
  belongs_to :task
end

目标是用户可以看到他们的任务,并在每个任务旁边启动和停止计时器。计时器很简单,只需创建一个日期并修改日期,以跟踪它运行的时间。

但是,在timers_controller中,我不确定如何创建计时器:

class TimersController < ApplicationController

def new
  @timer = Timer.new
end

def create
  @timer = current_user.build(timer_params)
end

private
  def timer_params
    params.require(:timer).permit(:start_time)
  end
end

我尝试过改变创建动作的结构以及参数,但到目前为止还没有任何效果。

对于一些其他上下文,这里是tasks / index.html.erb

    <% @tasks.each do |t| %>
  <%= t.title %>
  <%= form_for(@user.timers.build) do |f| %>
    <%= f.submit "Start", class: "btn btn-primary" %>
  <% end %>
  <br />
  <% end %>

这是定时器迁移:

class CreateTimers < ActiveRecord::Migration[5.1]
  def change
    create_table :timers do |t|
      t.integer :user_id
      t.integer :task_id
      t.datetime :start_time
      t.datetime :end_time

      t.timestamps
    end
    add_index :timers, :user_id
    add_index :timers, :task_id

  end
end

任务迁移:

class CreateTasks < ActiveRecord::Migration[5.1]
  def change
    create_table :tasks do |t|
      t.string :title
      t.text :description

      t.timestamps
    end
  end
end

2 个答案:

答案 0 :(得分:1)

这不是一个完整的答案,而是一些想法。

如果任务只有一个计时器,那么Joe Marion的回答可能是正确的。这似乎是合理的,但它不是你写的(任务也有很多计时器)。所以在这里你有另一种选择。

创建计时器时,它应与任务相关联(而不是直接与用户关联)。当然,您需要事先知道计时器属于哪个任务。 task_id应该是表单中的参数。

所以build命令应该是这样的

def create
  task = current_user.tasks.find_by(id: params[:task_id])
  if task
    @timer = task.timers.build(timer_params)
    if @timer.save
      # ....
    else
      # .....
  else
    # Error, task not found. Timer cannot be created
    # Whatever you want to do in this case ...
  end
end

在视图中,您的表单应与任务相关联,并且应包含要在创建操作中使用的task_id。

<% @tasks.each do |t| %>
  <%= t.title %>
  <%= form_for(t.timers.build) do |f| %>
    <!-- where is the start_time field? -->
    <%= f.hidden_field :task_id %>
    <%= f.submit "Start", class: "btn btn-primary" %>
  <% end %>
  <br />
<% end %>

答案 1 :(得分:0)

如果您想跟踪每项任务所花费的时间,您可以将一个计时器字段添加到user_tasks表中。

User.rb

class User < ApplicationRecord
  has_many :user_tasks
  has_many :tasks, through: :user_tasks
end

Task.rb

class Task < ApplicationRecord
  has_many :user_tasks
  has_many :users, through: :user_tasks
end

Timer.rb

class UserTasks < ApplicationRecord
  belongs_to :task
  belongs_to :user
end

UserTasks是一个连接表,用于表示用户的每个单独任务。因此,如果您在UserTasks表中添加了time_to_complete字段,则会显示每个用户的每个任务的时间。