2016-04-14 57 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