0

RoR モデルで高度な関係を構築しようとしています。

私が取り組んでいるのは、プロジェクトとタスクです。プロジェクトにはタスクがあり、ユーザーにはプロジェクトがあります。

プロジェクトに「サインアップ」したユーザーが、そのプロジェクト内のタスクに「サインアップ」できるようになりました。

私の現在のクラスの概要:

class AdminUser < ActiveRecord::Base
 has_and_belongs_to_many :projects
 has_and_belongs_to_many  :tasks
 has_many :admin_users_projects

[...]


class AdminUsersProject < ActiveRecord::Base

  belongs_to :admin_user
  has_and_belongs_to_many :project
  has_many :tasks

[...]

class Project < ActiveRecord::Base

  has_many :tasks
  has_and_belongs_to_many :admin_users
  has_and_belongs_to_many :admin_users_projects

[...]

class Task < ActiveRecord::Base

  belongs_to :project
  has_and_belongs_to_many :admin_users
  belongs_to :admin_users_project

[...]

スキーマは次のようになります。

 create_table "admin_users", :force => true do |t|
    t.string   "first_name",      :limit => 25
    t.string   "last_name",       :limit => 50
    t.string   "email",           :limit => 100, :default => "", :null => false
    t.string   "hashed_password", :limit => 40
    t.datetime "created_at",                                     :null => false
    t.datetime "updated_at",                                     :null => false
    t.string   "username",        :limit => 25
    t.string   "salt",            :limit => 40
  end

  add_index "admin_users", ["username"], :name => "index_admin_users_on_username"

  create_table "admin_users_projects", :force => true do |t|
    t.integer "admin_user_id"
    t.integer "project_id"
  end

  add_index "admin_users_projects", ["admin_user_id", "project_id"], :name =>     "index_admin_users_projects_on_admin_user_id_and_project_id"

  create_table "projects", :force => true do |t|
    t.string   "name"
    t.integer  "position"
    t.boolean  "visible",    :default => false
    t.datetime "created_at",                    :null => false
    t.datetime "updated_at",                    :null => false
  end

  create_table "tasks", :force => true do |t|
    t.integer  "project_id"
    t.string   "permalink"
    t.integer  "position"
    t.boolean  "visible"
    t.datetime "created_at",    :null => false
    t.datetime "updated_at",    :null => false
    t.string   "name"
    t.integer  "admin_user_id"
    t.integer  "progress"
  end

  add_index "tasks", ["permalink"], :name => "index_tasks_on_permalink"
  add_index "tasks", ["project_id"], :name => "index_tasks_on_project_id"

end

プロジェクトを表示するビューと、タスクのサブセットのビューがあります。ユーザーのプロジェクトを表示するビューもありますが、ユーザーのタスクのサブセットを表示したいと思います。

「admin_user_projects」に対する私の見解は、次のとおりです。

    <% @admin_users_projects.each do |admin_users_projects| %>
    <tr>
        <td><%= admin_users_projects.admin_user_id %></td>
        <td><%= admin_users_projects.admin_user.username  %></td>
        <td><%= admin_users_projects.project_id %></td>
        <td><%= admin_users_projects.project.name  %></td>
    </tr>
    <% end %>

これには、ユーザー ID、ユーザー名、プロジェクト ID、およびプロジェクト名が表示されます。ユーザーがそのプロジェクトに「サインアップ」しているタスクの数を示す行を追加したいと考えています。私が試してみました

        <td><%= admin_users_projects.tasks.size  %></td>

しかし、次を取得します。

Mysql2::Error: Unknown column 'tasks.admin_users_project_id' in 'where clause': SELECT COUNT(*) FROM `tasks`  WHERE `tasks`.`admin_users_project_id` = 1

これらの関係を効果的に機能させる方法を知っている人はいますか?

4

2 に答える 2

1

私の提案はこれです:

class AdminUser < ActiveRecord::Base
  has_and_belongs_to_many :projects
  has_many :assigned_tasks
  has_many :tasks, through: :assigned_tasks
end

class AssignedTask < ActiveRecord::Base
  belongs_to :user
  belongs_to :task

  validate :user_assigned_to_project

  private

  def user_assigned_to_project
    unless user.projects.include? task.project
      errors.add(:project, "is not valid")
    end
  end
end

class Project < ActiveRecord::Base
  has_and_belongs_to_many :admin_users
  has_many :tasks
end

class Task < ActiveRecord::Base
  has_many :assigned_tasks
  has_many :users, through: :assigned_tasks
  belongs_to :project
end


class GiantMigration < ActiveRecord::Migration
  create_table :admin_users do |t|
    # whatever
  end
  create_table :projects do |t|
    # whatever
  end
  create_table :assigned_tasks do |t|
    t.integer :admin_user_id, null: false
    t.integer :task_id, null: false
  end
  create_table :tasks do |t|
    # whatever
    t.integer :project_id
  end
  create_table :admin_users_projects, id: false do |t|
    t.integer :admin_user_id, null: false
    t.integer :project_id, null: false
  end
end

一般的な注意事項:

  • 純粋な結合テーブル (HABTM) を使用するか、結合モデル ( ) を使用するかを選択する必要がありますhas_many :through。今、あなたは2つを混ぜています。
  • force: true移行でデフォルトとして使用しないでください。
  • Rails の規則に固執する: has_and_belongs_to_many :projects(単数形でプロジェクトを使用)
于 2013-02-23T22:50:20.937 に答える
0

あなたは関係を持っていません

class AdminUsersProject < ActiveRecord::Base
  has_many :tasks

タスク テーブルに admin_users_project_id という名前の外部キーがない限り。

AdminUsersProjects リンク レコードのタスクはあまりないと思います。

代わりに、管理者ユーザーのタスクまたはプロジェクトのタスクが必要だと思います。

あなたが何を望んでいるかを明確にするまで、誰もあなたを助けることはできません。自分のやりたいことが明確になれば、自分で答えを見つけられるかもしれません。

于 2013-02-23T21:26:48.140 に答える