将一组用户ID添加到模型中 - Rails 4

时间:2016-03-11 08:25:43

标签: ruby-on-rails arrays select associations

我试图为学生发布一个应用程序来发布项目。当他们创建帖子时,他们可以添加他们的队友。每个学生都有一个用户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,那么创建项目的学生应该能够看到可能的选项列表。

然后在我的项目展示页面中,我想展示团队中的每个学生。

任何人都可以帮忙解决这个问题吗?我迷路了,不知道在哪里找到类似问题的例子。

更新

我发现了这篇文章:http://collectiveidea.com/blog/archives/2015/07/30/bi-directional-and-self-referential-associations-in-rails/

我很困惑。我不知道是否应该通过名为“团队”的联接表加入与用户的项目(通过我称之为团队的联接表),或者我是否应该与用户加入用户。

如果我将用户与项目联系起来,那么创建项目的用户可以选择其他用户作为项目团队成员。但是,说每个项目都有很多团队是不正确的(这个例子就是这个例子)。我不确定将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 %>

3 个答案:

答案 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,其中您的集合是与创建者属于同一组织的用户。请注意,此表单的一次提交一次只能创建一个项目成员。

我还没有测试过代码,但如果您遇到问题我会很乐意提供帮助。