在Rails中重构视图逻辑

Jak*_*old 1 ruby refactoring coding-style ruby-on-rails view

这就是我需要做的.我有一个Tournament模型,它连接到Uservia Signup(N:N).

唯一Signup增加的是注册状态.比赛有一个开始时间,用户只能在比赛开始前60分钟进行注册.之后,注册用户可以办理登机手续.所以基本上我有两种选择

简而言之,模型看起来像这样

class Signup < ActiveRecord::Base
  REGISTERED = 0
  CHECKED = 1

  belongs_to :tournament
  belongs_to :user
end

class Tournament < ActiveRecord::Base
  has_many :signups
  has_many :users, :through => :signups
end

class User < ActiveRecord::Base  
  has_many :signups
  has_many :tournaments, :through => :signups
end
Run Code Online (Sandbox Code Playgroud)

我跳过一些代码来保持这个简短.问题在于,因为我有很多条件要记住.这是我的实际代码(使用Slim作为模板引擎)

- if logged_in?
  - if current_user.registered_for?(@tournament)
    - if @tournament.starts_at < 60.minutes.from_now
      p Signups are closed, only registered users can now check in
      - if current_user.registered_for?(@tournament)
        = button_to "Checkin!", { :controller => :signups, :action => :update, :id => @tournament.id }, :method => :put
    - else
      = button_to "Cancel your registration for the tournament", { :controller => :signups, :action => :destroy, :id => @tournament.id }, :method => :delete
  - elsif current_user.checked_in?(@tournament)
    p You have already checked in.            
  - elsif @tournament.starts_at > 60.minutes.from_now
    = button_to "Sign up for the tournament", :controller => :signups, :action => :create, :method => :post, :id => @tournament.id
  - else
    p
      | The tournament starts in less than 60 minutes, you can't sign in
- else
  p 
    | You need to 
    |  
    = link_to "log in", login_path
    |  to play
Run Code Online (Sandbox Code Playgroud)

问题是,我不知道如何使这个更清洁.我的意思是,我可以为按钮添加助手,但这对我的if if else else丑陋无助,因为有许多不同的组合.这是一个简短的清单:

  • 用户未登录
  • 直到锦标赛开始并且用户尚未注册锦标赛,它才超过60
  • 直到比赛开始并且用户已经注册,它才超过60
  • 它不到60分钟,但用户尚未注册
  • 它不到60分钟,用户已注册,但尚未办理登机手续
  • 它不到60分钟,用户已经签到

这只是冰山一角,因为管理员应该看到比普通用户更多的信息,但我不想让这个问题复杂化.

主要问题是,我应该如何处理这样的案件?在视图中这样做似乎太可怕了,但我没有看到任何其他更简单的方法.

Dom*_*let 5

更简洁的方法是在模型上创建有意义的方法.例如,在您的锦标赛模型中,添加以下内容:

def can_register?( user )
  !user.registered_for?(self) && self.starts_at > 60.minutes.from_now
end
Run Code Online (Sandbox Code Playgroud)

然后在您的视图中,您可以can_register?在显示内容之前进行检查.像你一样在视图中添加逻辑并不是MVC应用程序的目的.