Nano Hash - криптовалюты, майнинг, программирование

Добавление массива идентификаторов пользователей в модель — Rails 4

Я пытаюсь сделать приложение для студентов, чтобы публиковать проекты. Когда они создают публикацию, они могут добавлять своих товарищей по команде. У каждого студента есть идентификатор пользователя, и я хочу, чтобы студент, создающий проект, мог выбирать другие идентификаторы из той же организации, что и их товарищи по команде. Ассоциации моделей:

пользователь

has_and belongs_to_many :projects

проект

has_and belongs_to_many :users

У меня есть модель проекта с:

:user_id (integer)
:team_mates (integer)

В форме моих проектов я хочу, чтобы студент (создающий проект) выбирал другие идентификаторы (из списка студентов, принадлежащих к одной организации) в качестве товарищей по команде. Мой первый вопрос: должен ли атрибут товарищей по команде быть целым числом (поскольку может быть более одного товарища по команде, и в этом случае может ли этот атрибут содержать массив?

Моя следующая проблема: я не знаю, как это сделать. Если я добавлю строку выбора в форму своего проекта, чтобы добавить user_ids, где user.organisation соответствует текущему идентификатору пользователя, тогда учащийся, создающий проект, должен увидеть список возможных вариантов.

Затем на странице показа моих проектов я хочу отобразить каждого ученика в команде.

Может ли кто-нибудь помочь с тем, как подойти к этому? Я потерялся и застрял в поисках примеров подобных проблем.

ОБНОВИТЬ

Я нашел эту статью: http://collectiveidea.com/blog/archives/2015/07/30/bi-directional-and-self-referential-associations-in-rails/

Хотя я в замешательстве. Я не знаю, следует ли мне присоединяться к проектам с пользователями (через таблицу соединений, которую я назвал «команды»), или мне следует объединять пользователей с пользователями через таблицу соединений, называемую «команды».

Если я присоединяю пользователей к проектам, для меня имеет смысл, что пользователь, создающий проект, может выбирать других пользователей в качестве товарищей по команде проекта. Однако неверно утверждать, что в каждом проекте много команд (что и показано в этом примере). Я не уверен в изменении has_many на has_one, так как в статье далее объясняется, как has_many через соединение.

Если я присоединяю пользователей к пользователям, то пользователь со многими проектами может иметь разные команды для каждого проекта. Так что это было бы не правильно.

Взяв статью за пример, я попробовал:

создать модель команд:

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

Команда.рб

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

проект.rb

has_one :team
has_many :team_mates, through: :teams, dependent: :destroy

Я изменил это, чтобы у проектов была одна команда, а не много.

Я смущен этим и не уверен, как это запустить. В форме моих проектов я хочу предложить пользователям (которые создают проекты) выбирать профили других пользователей, которые являются товарищами по команде. Я потерялся в этот момент.

Я попытался сделать Teams Helper:

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>

ПРЕДЛОЖЕНИЕ ВИШАЛА

Приняв предложение Вишала, я реализовал предложенную структуру. У меня проблема с формой проектов. Моя полная установка:

Модели Организация

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

Моя структура такова, что профили принадлежат пользователям. В пользователе у меня есть метод, называемый формальным именем, который добавляет заголовок к имени пользователя.

Когда я сохраняю это и пробую, я получаю сообщение об ошибке:

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 %>

Ответы:


1

Представьте Team модель с has_and belongs_to_many отношениями между Userмоделью и team моделью. Затем Team представляет собой массив из User объектов.

11.03.2016
  • Разве не между проектом и командой? Какими будут атрибуты этой модели и как заставить их работать в моей модели проекта? 11.03.2016
  • да, кроме того, между project и team будет связь. Если для каждого project имеется ровно один столбец team, то вы просто добавляете столбец team_id в свою модель project, а также отношение belongs_to. Отношение между user и team аналогично отношению между user и project, которое у вас уже есть. Ага, может быть, ваш projects ведет себя в этом отношении как teams? Тогда вам вообще не нужна была бы модель team. 11.03.2016
  • Я вообще этого не понимаю. Вы пришли к выводу, что командная модель не является решением? 11.03.2016

  • 2

    То, что вам нужно, это самореферентные ассоциации. Вам нужно будет создать таблицу соединений, в которой хранятся записи о том, какой пользователь является членом команды какого пользователя; что-то вроде следующего:

    +-----------+----------------+------------+-------------+
    |  user_id  | team_member_id | created_at | updated_at  |
    +-----------|----------------+------------+-------------+
    |           |                |            |             |
    +-----------+----------------+------------+-------------+
    
    11.03.2016
  • Итак, вы думаете, что мне нужна новая таблица для членов команды, а также таблица соединений вместо атрибута в модели проекта (для товарищей по команде)? 11.03.2016
  • Да, безусловно. Потому что у одного пользователя может быть несколько товарищей по команде. 11.03.2016
  • Но как добавить это в проект? В разных проектах могут быть разные товарищи по команде 11.03.2016

  • 3

    Вы можете думать о том, «какой ресурс вы создаете». Когда вы добавляете новый проект, вы создаете ресурс проекта. Когда создатель проекта добавляет кого-то еще в проект, вы создаете ресурс ProjectMemberRelationship. Итак, я думаю, вы можете получить то, что вам нужно, используя только эти модели — Organization, User, Project, 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", так как имя столбца не user_id, как ожидается Rails по умолчанию. И вам нужно source: :project, потому что имя столбца не Collabored_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 добавленного пользователя, в то время как таблицы пользователей и проектов не затрагиваются этим действием. .

    Разделим задачу на 2 остановки.

    Шаг 1: Пользователь создает проект.

    Шаг 2: Пользователь добавляет соавторов в проект.

    Шаг 1 довольно прост и понятен. Вы создаете проект, скажем, с его темой и user_id пользователя, который его создал.

    Теперь на странице показа проекта у вас может быть форма для добавления нового project_member_relationship. Вам нужно только 2 поля для отправки здесь — member_id (для добавляемого пользователя) и project_id (что равно params[:id] на странице проектов#show). Для поля member_id вы можете использовать collection_select, где ваша коллекция — это пользователи, принадлежащие к той же организации, что и создатель, если требуется. Имейте в виду, что одна отправка этой формы создает только одного участника проекта за раз.

    Я еще не тестировал код, но буду рад помочь, если у вас возникнут проблемы.

    15.03.2016
  • Привет Вишал. Большое спасибо за эту помощь. Я вижу, что вы предлагаете здесь, и я думаю, что это имеет смысл. 16.03.2016
  • Надеюсь, это сработает для вас и принесет ожидаемый результат. Ваше здоровье! 16.03.2016
  • Извините, Вишал, таймер комментариев истек. Я вижу, вы следовали логическому подходу из примера, на который я ссылался изначально, о двунаправленных ассоциациях, где два соединяемых объекта связаны через модель соединения, и объекты имеют много таких соединений. . Мне интересно, имеет ли смысл проектировать отношения так, чтобы: - Проект владел экземпляром модели под названием «Команда» - Команда имеет отношения ко многим профилям - Каждый проект имеет ровно одну команду, а каждая команда имеет ровно одну Проект 16.03.2016
  • Таким образом, это будет отличаться от приведенного выше решения, где каждый проект имеет много связей project_member_relationship, и каждая связь project_member_relationships представляет собой однозначное сопоставление проекта с профилем. 16.03.2016
  • Мне интересно, есть ли какое-то соглашение о программировании/структурировании данных, чтобы подойти к нему первым способом? Я предполагаю, что в будущем могут быть некоторые преимущества, если делать более сложные запросы по этим отношениям, если это так. Считаете ли вы, что один способ технически предпочтительнее другого? 16.03.2016
  • Я думаю, это сводится к вашему требованию. Есть ли какие-то особые атрибуты, которыми должна обладать команда? Если нет, то вам нужно подумать, нужна ли дополнительная модель (и таблица базы данных) для команды. Если вы введете модель Team, вам также потребуется ввести еще одну модель, которая связывает команду с пользователем — с полями team_id и user_id — которая служит цели модели ProjectMemberRelationship в ответе. 16.03.2016
  • В последнем случае, если вы запрашиваете, скажем, пользователей определенного проекта, вам нужно будет пройти по этому пути — проект -> команда -> команда_отношения_пользователей -> пользователи. Тогда как без модели «Команда» вы будете делать это — проект —> проект-члены-отношения —> пользователи. Обратите внимание на дополнительный слой «команда». Поэтому я бы добавил дополнительную модель, только если уверен в ее полезности. Сказав это, это просто «мой» способ мышления, и я все еще новичок в Rails. 16.03.2016
  • Если вам нужно что-то вроде project1 = Project.find(1), а затем project1.team, чтобы получить коллекцию членов проекта, вы всегда можете определить функцию/метод в модели проекта, которая вернет вам эту коллекцию/команду. 16.03.2016
  • Привет, Вишал, я добавил свою попытку попробовать ваше предложение выше. Ты видишь, что я сделал не так? 18.03.2016
  • Конечно. Можете ли вы опубликовать полную форму? Это помогло бы разобраться. 18.03.2016
  • Похоже, вы вызываете team_mate_id в «проекте», хотя на самом деле это атрибут «команда». 18.03.2016
  • Но не вместо «члена» в вашем примере. Если я изменяю team_mate_id на team_id, я получаю ту же ошибку: неопределенный метод 'team_id' 18.03.2016
  • Я все еще получаю сообщение об ошибке, если я изменяю его на: has_one :team has_many :team_mates через: :team 18.03.2016
  • Можете ли вы опубликовать полную форму, пожалуйста? 18.03.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..