2012-11-19 55 views
1

我创建了一个简单的Rails应用程序,其中用户可以报名参加事件在Rails“用户”在同一时间。为了创造令人愉快的用户体验,未识别的用户可以浏览事件,然后如果他们看到他们想要举办活动的事件,则可以点击“注册事件”。使用Twitter Bootstrap,应用程序会向用户呈现一个模式(弹出窗口),要求他们先注册,然后参加该活动。如何让一个人一个“事件”注册,并创建

上模态的形式如下:

simple_form_for @user do |f| 
    f.input :name, :placeholder => "Name", :label => false 
    f.input :email, :placeholder => "Email", :label => false 
    f.input :postcode, :placeholder => "Postcode", :label => false 
    hidden_field_tag :event_id, @event.id 
    f.button :submit, "Sign me up for this event" 
end 

所以,你可以看到,基本上我传递一个事项标识值用户控制器的创建行动。为了解决这个问题的创建操作变为:

def create 
    if params[:event_id].blank? 
     event_registration = false 
    else 
     event_id = params[:event_id].to_s 
     event_registration = true 
    end 

    if event_registration == true 
     # The user is being created as part of signing up to an event 
     @user_check = User.find_by_email(params[:user][:email]) 

     unless @user_check.nil? 
     # The user already exists, but the visitor forgot 
     @user = @user_check 
     else 
     # The user is a new sign up 
     @user = User.new(params[:user]) 
     end 

     # Now create the attendance for the user 
     @event = Event.find(event_id) 
     @attendance = @event.attendances.new 
     @attendance.attendee = @user 
     @attendance.save 

     redirect_target = event_attendance_thank_path(@event, @attendance) 

    else 
     # The user is being created cleanly 

     @user = User.new(params[:user]) 
    end 

    if @user.save 
     redirect_to root_path, notice: "Thanks for signing up, check your email" 
    else 
     # We should destroy the failing attendance? 
     redirect_to root_path, alert: "Something's up with the signup. Have you already registered with this email address?" 
    end 
    end 

对我来说,处理这种复杂的控制器中的感觉乱了,我不知道还有什么更好的方法,我可能会去这件事吗?

任何帮助或指针重构这将不胜感激。

回答

0

如果已经签名并登录的用户可能标记出席事件,则应在两个地方使用相同的代码。只需创建一个帮助器,标记用户的出席情况,并从UsersController#createEvents#attend(或其他所谓的操作)中调用它。

现在 - 如果您听说过“胖模型,瘦身控制器”模式,您可能已经开始注意到这是一个可以使用它的地方。

只需创建User模型方法参加某个事件,即将接受id或事件本身作为参数。这样,你可以简单地写在你的控制器:

User.create(...).tap do |user| 
    user.attend(params[:event_id]) if params[:event_id] 
end 
+0

非常好 - 谢谢你,我以前没有遇到过轻拍方法,看起来很有趣。 – idrysdale

+0

请注意'#tap'方法在这里完全不需要。这是在创建或发现之后后处理某些对象的好方法。这里真正重要的是在'User'模型中定义'#attend'方法。 – samuil

+0

这很酷,我明白了。感谢您的建议! – idrysdale

相关问题