CNuts CNuts - 4 months ago 18
Ruby Question

Add User to project using his email

I have projects which can have one

projectOwner
and multiple
projectMembers
. After creating my project, I want to be able to add users to this project.

Right now my problem is that I have to enter the
user_id
and
project_id
when creating a new
projectMember
. The form is expecting a
user_id
and
project_id
so how can I change that so that it takes an
email
and then finds the
user_id
related to it.

View:

<%= form_for([@project, @project.project_members.build]) do |f| %>
<p>
<%= f.label :project_id %><br>
<%= f.text_field :project_id %>
</p>
<p>
<%= f.label :user_id %><br>
<%= f.text_field :user_id %>
</p>
<p>
<%= f.submit :Add, class: 'btn btn-info' %>
</p>
<% end %>


Controller:

def create
@project_member = ProjectMember.new(member_params)
@project_member.save
end

private
def member_params
params.require(:project_member).permit(:user_id, :project_id)
end


Model relation:

class User < ApplicationRecord
has_many :roles
has_many :projects, through: :roles
end

class Role < ApplicationRecord
belongs_to :user
belongs_to :project
end

class ProjectOwner < Role
end

class ProjectMember < Role
end

class Project < ApplicationRecord
has_many :project_members
has_many :members, class_name: "User", through: :project_members
has_one :project_owner
has_many :owners, class_name: "User", through: :project_owner
end


Right now my routes look like this but I feel like this isnt the right way of doing it:

devise_for :users

resources :users do
resources :projects
end

resources :projects do
resources :project_members
end

Answer Source

The form is expecting a user_id and project_id so how can I change that so that it takes an email and then finds the user_id related to it.

You can have an input for the email in the form and allow the controller to do the rest

<%= form_for([@project, @project.project_members.build]) do |f| %>
  <p>
   <%= f.label :project_id %><br>
   <%= f.text_field :project_id %>
  </p>
  <p>
   <%= label_tag :email %><br>
   <%= email_field_tag :email %>
  </p>
  <p>
   <%= f.submit :Add, class: 'btn btn-info' %>
  </p>
<% end %>

In the controller, find the user with the email

def create
  @project_member = ProjectMember.new(member_params)
  @user = User.find_by(email: params[:email])
  @project_member.user_id = @user.id
  @project_member.save
end

Also, you don't need to provide project_id explicitly in the form. The @project in the form will give you the project_id. You just need to let the controller do the mapping

<%= form_for([@project, @project.project_members.build]) do |f| %>
  <p>
    <%= label_tag :email %><br>
    <%= email_field_tag :email %>
  </p>
  <p>
    <%= f.submit :Add, class: 'btn btn-info' %>
  </p>
<% end %>

In the controller,

def create
  @project = Project.find(params[:project_id])
  @project_member = @project.project_members.new(member_params)
  @user = User.find_by(email: params[:email])
  @project_member.user_id = @user.id
  @project_member.save
end