2016-04-14 60 views
0

這是事情。我有用戶和活動,我希望他們之間有邀請。這是用戶可以邀請其他人蔘加活動。軌道邀請事件和用戶控制器

我創建了一個Invitations控制器和模型。這個模型看起來像這樣

user_id: (user being invited), event_id:(event_to_attend), inviter: (sent_the_invite) 

我建立從控制器我被邀請去/請柬/新提交表單,但我不能讓他們的工作。他們是之前創建的,但我做了一些修改,但他們沒有創建,他們只是說「邀請已發送」,但沒有在控制檯或任何內容中創建邀請。

我知道他們的工作,因爲在控制檯中我做

a=User.first 
a.invitations.build(event_id: 1, inviter:2) 
a.save 

,然後我可以看到邀請和user_id是誰創造了邀請,一個在這種情況下,我可以看到的邀請,並可以在一通過調用Event中的.invitees方法來獲取用戶。所以協會的工作。但我無法通過表單創建它。

這裏的形式

<%= form_for(@invitation) do |f| %> 

<% userArray=User.all.select{|u| u.name unless u==current_user }%> 
<% names=userArray.map{|u| u.name} %> 
<% events=current_user.attended_events.map{|u| u.description} %> 

<%= f.label :event %> 
<%= f.select :event, events %> 

<%= f.label :user %> 
<%= f.select :user, names %> 

<%= f.submit "Send" %> 

<% end %> 

我只用用戶和事件的描述名稱爲UX

這裏是我的邀請控制器

類InvitationsController < ApplicationController的 包括ApplicationHelper 高清新 @邀請= Invitation.new 結束

def create #不考慮,重複的用戶和同一用戶的同名事件。

#user being invited 
@user=User.find_by(name: params[:invitation][:user]) 


#event being invited to 
@event=Event.find_by(description: params[:invitation][:event]) 


#Inviter is current user, invitee is @user 
@user.invitations.build(event_id: @event.id, inviter: current_user.id) 

#Event not in user.attended_events 
if !(@user.attended_events.where(id: @event.id) || \ 
    @user.invitations.where("[email protected] AND [email protected]")) 

    flash.now[:danger]="User is already going to the event" 
    render 'foo' 
    #render 'new' 

elsif @user.save! 
    flash[:success]="Invitation was SENT!" 
    redirect_to new_invitation_path 
else 
    flash.now[:danger]="Please select both options" 
    render 'foobar' 
    #render 'new' 
end 
    end 

回答

0

你對自己的要求比自己的要難得多。

您可以通過使用rails collection helpers清理的形式開始:

<%= form_for(@invitation) do |f| %> 
    <div class="row"> 
    <%= f.label :event_id %> 
    <%= f.collection_select :event_id, Event.all, :id, :name, prompt: true %> 
    </div> 

    <div class="row"> 
    <%= f.label :user_id %> 
    <%= f.collection_select :user_id, User.where.not(id: @invitation.inviter.id), :id, :name, prompt: true %> 
    </div> 

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

這是假設你有一個current_user方法和您的事件和用戶有您要使用的標籤名稱屬性(你可以使用任何你想要的屬性)。實際使用的值是相關記錄的ID。

請注意,我們使用參數鍵event_iduser_id。使用event會導致錯誤,因爲setter需要一個實際的事件實例而不僅僅是一個ID。

你會在你的控制器處理這像這樣:

class InvitationsController < ActiveRecord::Base 
    def new 
    @invitation = current_user.invitations.new 
    end 

    def create 
    @invitation = current_user.invitations.new(invitation_params) 
    @invitation.save 
    respond_with(@invitation) 
    end 

    private 
    def invitation_params 
     params.require(:invitation).permit(:event_id, :user_id) 
    end 
end 

這不處理還通過創建重複邀請函的問題。處理這種情況的Rails的方法是將一個獨特的驗證到模型:

class Invitation < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :invitation 
    belongs_to :inviter, class_name: 'User' 
    validates_uniqueness_of :user_id, 
    scope: 'invitation_id', 
    message: 'is already going to the event' 
end 

這將導致@invitation.save如果用戶已經被邀請失敗,再次渲染new視圖。

Due to the possibility of race conditions您應該支持使用數據庫索引進行驗證。

# generate with 
# $ rails g migration AddUniqueIndexToInvitation 
class AddUniqueIndexToInvitation < ActiveRecord::Migration 
    def change 
    add_index :invitations, [:user_id, :event_id], unique: true 
    end 
end