我试图为学生发布一个应用程序来发布项目。当他们创建帖子时,他们可以添加他们的队友。每个学生都有一个用户ID,我希望创建项目的学生能够从与他们的队友相同的组织中选择其他ID。模型关联是:
用户
has_and belongs_to_many :projects
项目
has_and belongs_to_many :users
我有一个项目模型,其中包含:
:user_id (integer)
:team_mates (integer)
在我的项目表单中,我希望学生(创建项目,选择其他ID(来自属于同一组织的学生列表)作为队友。我的第一个问题是团队成员属性是否应该是整数(因为可能有多个队友,在这种情况下,这个属性可以包含数组吗?
我的下一个问题是 - 我因为如何解决这个问题而迷失了方向。如果我在项目表单中添加一个选择行,添加user_ids,其中user.organisation等于当前用户的id,那么创建项目的学生应该能够看到可能的选项列表。
然后在我的项目展示页面中,我想展示团队中的每个学生。
任何人都可以帮忙解决这个问题吗?我迷路了,不知道在哪里找到类似问题的例子。
更新
我很困惑。我不知道是否应该通过名为“团队”的联接表加入与用户的项目(通过我称之为团队的联接表),或者我是否应该与用户加入用户。
如果我将用户与项目联系起来,那么创建项目的用户可以选择其他用户作为项目团队成员。但是,说每个项目都有很多团队是不正确的(这个例子就是这个例子)。我不确定将has_many更改为has_one,因为文章继续解释has_many通过join。
如果我将用户加入用户,那么拥有许多项目的用户可能会为每个项目拥有不同的团队。所以这不正确。
以文章为例,我尝试了:
创建团队模型:
class CreateTeams < ActiveRecord::Migration
def change
create_table :teams do |t|
t.references :project, index: true, foreign_key: true
t.references :team_mate, index: true
t.timestamps null: false
end
add_foreign_key :teams, :projects, column: :team_mate_id
add_index :teams, [:project_id, :team_mate_id], unique: true
end
end
Team.rb
belongs_to :project
belongs_to :team_mate, class_name: "Profile"
团队控制员(我稍后会想到这一点 - 因为我还没有匹配制作者部分,所以现在评论了):
class TeamsController < ApplicationController
before_action :resync_matches, only: :index
def index
# several orders of magnitude faster
@team_mates = current_user.team_mates
.page(params[:page])
end
private
def resync_matches
# only resync if we have to
if current_user.teams_outdated?
new_matches = MatchMaker.matches_for(current_user)
current_user.team_mates.replace(new_matches)
end
end
end
project.rb
has_one :team
has_many :team_mates, through: :teams, dependent: :destroy
我改变了这一点,以便项目有一个团队而不是很多。
我对此感到困惑,不知道如何启动并运行。在我的项目表单中,我想为用户(创建项目)提供选择其他队友配对的配置文件。我此时已经迷失了。
我试图组建一个团队助手:
module TeamsHelper
def team_mate_options
s = ''
Profile.in_same_organisation.each do |profile|
s << "<option value='#{profile.id}'>#{profile.user.full_name}</option>"
end
s.html_safe
end
end
在我的profile.rb中,我尝试制作一个范围来获取与项目创建者属于同一组织的个人资料(虽然我不确定这是否正确):
scope :in_same_organisation, -> (organisation_id) { where(organisation_id: organisation_id) }
然后在我的项目表单中,我尝试添加一个选择选项:
<div class="form-group">
<%= label_tag 'team_mates', 'Choose team mates' %>
<%= select_tag 'team_mates', team_mate_options, multiple: true, class: 'form-control chosen-it' %>
</div>
VISHAL&#39; S建议
根据Vishal的建议,我已经实施了提议的结构。我对项目表格有疑问。我的完整设置是:
模型 组织
has_many :profiles
资料
has_many :projects
belongs_to :organisation
has_many :teams, foreign_key: "team_mate_id"
has_many :team_projects, through: :teams, source: :project
项目
belongs_to :profile
has_many :teams
has_many :team_mates, through: :teams
队
belongs_to :project
belongs_to :team_mate, class_name: "Profile"
我的团队表有:
create_table "teams", force: :cascade do |t|
t.integer "project_id"
t.integer "team_mate_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
然后在我的项目表格中,我有:
<%= f.label :team_mates, :label => "Add a team member" %>
<%= f.collection_select(:team_mate_id, Profile.all, :id, :team_mate_select, {prompt: "Select the team member"}, {:required => true}) %>
在我的个人资料模型中,我有:
def team_mate_select
self.user.formal_name
end
我的结构是个人资料属于用户。在用户中,我有一个名为formal name的方法,它为用户名添加标题。
当我保存并尝试时,我收到一条错误消息:
undefined method `team_mate_id' for #<Project:0x007fa08ed3d8e0>
(突出显示项目表单的集合选择行)
我的项目/ form.html.erb有:
<%= simple_form_for(@project) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title, :label => "Title", autofocus: true %>
<%= f.input :description, :as => :text, :label => "Describe your project", :input_html => {:rows => 10} %>
<%= f.input :remark, :as => :text, :label => "Is there an interesting fact or statistic that's relevant to this research?", :input_html => {:rows => 5}, :placeholder => "In fact, ...(insert a fact which shows why this research might be interesting or relevant)" %>
<%= f.input :hero_image, :label => "Add an image" %>
<%= f.label :team_mates, :label => "Add a team member" %>
<%= f.collection_select(:team_id, Profile.all, :id, :team_mate_select, {prompt: "Select the team member"}, {:required => true}) %>
<div class="form-actions" style="margin-top:50px">
<%= f.button :submit, "Create", :class => 'formsubmit' %>
</div>
<% end %>
答案 0 :(得分:0)
引入Team
模型,has_and belongs_to_many
模型与User
模型之间存在team
关系。然后,Team
表示User
个对象的数组。
答案 1 :(得分:0)
您要找的是self-referential associations。您必须创建一个连接表,以保存哪个用户是哪个用户的团队成员的记录;类似的事情:
grunt.registerTask('default', ['coffee', 'concurrent']);
答案 2 :(得分:0)
您可以根据“您正在创建的资源”进行思考。添加新项目时,您正在创建项目资源。当项目的创建者将其他人添加到项目中时,您将创建ProjectMemberRelationship资源。所以,我认为只有这些模型才能得到你所需要的东西 - 组织,用户,项目,ProjectMemberRelationship(以及每个模型的表格)。
您需要一个通过user_id字段引用用户的项目表。
使用
创建ProjectMemberRelationship模型rails generate model ProjectMemberRelationship project_id:integer member_id:integer
组织模式:
has_many :users
用户模型:
belongs_to :organization
has_many :projects
has_many :project_member_relationships, foreign_key: "member_id"
has_many: collaborated_projects, through: :project_member_relationships, source: :project
您需要foreign_key: "member_id"
,因为Rails默认情况下列名不是user_id。您需要source: :project
因为列名不是collaborated_project_id而是project_id。
项目模型:
belongs_to :user
has_many :project_member_relationships
has_many :members, through: :project_member_relationships
ProjectMemberRelationship模型:
belongs_to :project
belongs_to :member, class_name: "User"
使用上面定义的模型,每次将成员添加到项目时,都会向project_member_relationships表添加一个新行,该表存储项目的project_id和添加的用户的member_id,而用户&amp;项目表不受此操作的影响。
让我们将任务分成2站。
第1步:用户创建项目。
第2步:用户将协作者添加到项目中。
第1步非常简单明了。您可以创建一个项目,例如创建项目的用户的主题和user_id。
现在,在项目的展示页面上,您可以使用表单添加新的project_member_relationship。您只需要在此处提交2个字段 - member_id(对于要添加的用户)&amp; project_id(等于项目#show页面上的params [:id]。对于member_id字段,您可以根据需要使用collection_select,其中您的集合是与创建者属于同一组织的用户。请注意,此表单的一次提交一次只能创建一个项目成员。
我还没有测试过代码,但如果您遇到问题我会很乐意提供帮助。