Rails 4 - Invite team mates to project

2019-09-19 05:27发布

问题:

Im trying to add functionality to my Rails 4 app which allows a user (who creates a project) to invite others to join their project team.

I found this tutorial, which I've found helpful: https://coderwall.com/p/rqjjca/creating-a-scoped-invitation-system-for-rails

To this point, I have the following set up:

User

has_one :profile, dependent: :destroy

Profile

belongs_to :user
has_many :teams, foreign_key: "team_mate_id"

  has_many :team_projects, through: :teams, source: :project
  has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
  has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'

Project

belongs_to :profile
    has_one :team
    has_many :team_mates, through: :team
    has_many :invites

Invite

 belongs_to :project
      belongs_to :sender, :class_name => 'Profile'
      belongs_to :recipient, :class_name => 'Profile'

Team

belongs_to :project
  belongs_to :team_mate, class_name: "Profile"

In my form, I have:

<%= simple_form_for(@invite, :url => invites_path) do |f| %>
            <%= f.hidden_field :project_id, :value => @invite.project_id %>
            <%= f.label :email %>
            <%= f.email_field :email %>
            <%= f.input :expiry, :as => :date_picker, :label => "When do you need a response to this invitation?"  %>

            <%= f.submit 'Send' %>
            <% end %>

Then in my show (rendered on the projects show) I have:

<%= render :partial => 'projects/invite_team_mate'  %>

In my invites controller, I have:

class InvitesController < ApplicationController

    def new
      @invite = Invite.new
    end

    def create
      @invite = Invite.new(invite_params)
      @invite.sender_id = current_user.profile.id
      if @invite.save

        #if the user already exists
        if @invite.recipient != nil 

           #send existing user email invitation to join project team
           InviteMailer.existing_user_invite(@invite).deliver 

           #Add the user to the user group - inivte rsvp pending
           @invite.recipient.project.push(@invite.project)
        else
            #send new user email invitation to join as a user and this project team
           @invite.recipient.project.push(@invite.project)

           # InviteMailer.new_user_invite(@invite, new_user_registration_path(:invite_token => @invite.token)).deliver
        end
      else
         # oh no, creating an new invitation failed
      end
    end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_invite
      @invite = Invite.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def invite_params
      params[:invite].permit(:email)
    end   
end 

I can't figure out what else needs to happen to make this work.

When I save all this and try to invite an email address, I get this error:

undefined method `project' for nil:NilClass

That happens despite the form I use to send the invite being shown on the projects show page.

回答1:

You need to add project_id and recipient_id to your invite_params, and add the recipient to your form (as a text_field, or hidden field, depending on your use case):

# controller
def invite_params
  params[:invite].permit(:email, :project_id, :recipient_id)
end   

# form
<%= simple_form_for(@invite, :url => invites_path) do |f| %>
  ...
  <%= f.hidden_field :recipient_id, :value => get_recipient_id %>
  ...
<% end %>


回答2:

Error is due to @invite.project_id, because @invite has no data so it's throwing error

<%= f.hidden_field :project_id, :value => @invite.project_id %>

replace this with or with some other desired logic

select_tag "people", options_from_collection_for_select(@projects, "id", "name")

In controlller

def new
  @invite = Invite.new
  @projects = current_user.team_projects // here you have to add your logic, for which project you want to invite or let me know 
end


回答3:

I'm finding following code very strange

if @invite.recipient != nil 
    ...
   #Add the user to the user group - inivte rsvp pending
   @invite.recipient.project.push(@invite.project)
else
    #send new user email invitation to join coalfacer and this project team
   @invite.recipient.project.push(@invite.project)
   ...
end

How is that you call the same code @invite.recipient. even if @invite.recipient is Nil?!

By the way, ensure you understand why this code is written for in the controller, what it means

def invite_params
  params[:invite].permit(:email)
end   

For your convenience, refrain from coping code you don't understand. Also, even if you do so, do that in small portions and try after each one, so you can localize the error if any. Working in small increments is essential. You can't do a horde of changes and then just ask "what's wrong about his plenty of code".

Finally, I suggest you write specific questions, using MCVE principle. You have to extract specific portions of your code relevant to the issue, and be specific on the problem. If you put whole bunch of code, including irrelevant one, it's much much harder to help.