簡體   English   中英

使用has_many通過:關系創建記錄

[英]Creating a record with a has_many through: relationship

我在Rails中使用has_many通過:關系創建記錄時遇到了麻煩。 我有一個用戶模型,一個任務模型和一個計時器模型。 這個想法是,用戶has_many :tasks以及has_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

我嘗試過更改create動作的結構以及參數,但到目前為止沒有任何效果。

對於其他一些上下文,這里是task / 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

這不是一個完整的答案,而是一些想法。

如果一項任務只有一個計時器,則喬·馬里昂的答案可能是正確的。 這似乎很合理,但這不是您編寫的( Tasks也有很多計時器 )。 因此,這里還有另一個選擇。

創建計時器時,應將其與任務關聯(而不是直接與用戶關聯)。 當然,您需要提前知道計時器屬於哪個任務。 task_id應該是表單中的參數。

所以構建命令應該是這樣的

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

在視圖中,您的表單應與任務關聯,並應包含在create操作中使用的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 %>

如果要跟蹤每個任務花費的時間,可以將一個計時器字段添加到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字段,它將顯示每個用戶每個任務的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM