如何有效地减少rails代码?

时间:2016-01-06 09:03:32

标签: ruby ruby-on-rails-4

在Projects控制器中我有5种方法:

def day1
end

def day2
end

def day3
end

def day4
end

def day5
end

在我的观点中:

day1.html.erb
day2.html.erb
day3.html.erb
day4.html.erb
day5.html.erb

在每个单独的视图中,我都有一段与此类似的代码:

在day1.html.erb中:

<% if current_user.speed? || current_user.admin? %>
  "Display Day 1"
<% else %>
  <% unless current_user.day_count.nil? %>
    <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 1 %>
      "Display Day 1"
    <% else %>
      "This project cannot open now. Please wait until day1!"
    <% end %>
  <% end %>
<% end %>

在day2.html.erb中:

<% if current_user.speed? || current_user.admin? %>
  "Display Day 2"
<% else %>
  <% unless current_user.day_count.nil? %>
    <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 2 %>
      "Display Day 2"
    <% else %>
      "This project cannot open now. Please wait until day2!"
    <% end %>
  <% end %>
<% end %>

依此类推,直到第5天。

在routes.rb中:

match 'projects/day-1' => "projects#day1", :via => [:get], as: "day1"
match 'projects/day-2' => "projects#day2", :via => [:get], as: "day2"
match 'projects/day-3' => "projects#day3", :via => [:get], as: "day3"
match 'projects/day-4' => "projects#day4", :via => [:get], as: "day4"
match 'projects/day-5' => "projects#day5", :via => [:get], as: "day5"

在index.html.erb视图中我有:

<% if current_user.speed? || current_user.admin? %>
  <div class="day_tracking">
    <div class="day_passed"><span>✔</span><p>1</p></div>
    <div class="day_passed"><span>✔</span><p>2</p></div>
    <div class="day_passed"><span>✔</span><p>3</p></div>
    <div class="day_passed"><span>✔</span><p>4</p></div>
    <div class="day_passed"><span>✔</span><p>5</p></div>
  </div>
<% else %>
  <% unless current_user.day_count.nil? %>
    <div class="day_tracking">
      <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 1 %>
        <div class="day_passed"><span>✔</span><p>1</p></div>
      <% else %>
        <div class="day_left"><span>✘</span><p>1</p></div>
      <% end %>

      <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 2 %>
        <div class="day_passed"><span>✔</span><p>2</p></div>
      <% else %>
        <div class="day_left"><span>✘</span><p>2</p></div>
      <% end %>

      <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 3 %>
        <div class="day_passed"><span>✔</span><p>3</p></div>
      <% else %>
        <div class="day_left"><span>✘</span><p>3</p></div>
      <% end %>

      <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 4 %>
        <div class="day_passed"><span>✔</span><p>4</p></div>
      <% else %>
        <div class="day_left"><span>✘</span><p>4</p></div>
      <% end %>

      <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= 5 %>
        <div class="day_passed"><span>✔</span><p>5</p></div>
      <% else %>
        <div class="day_left"><span>✘</span><p>5</p></div>
      <% end %>
    </div>
  <% end %>
<% end %>

代码的作用非常简单。首先,我检查current_user是否是管理员或速度用户。如果是,则显示:

✔1 ✔2 ✔3 ✔4 ✔5 
( It means he can see all the projects )

否则,如果current_user不是速度用户或管理员,则显示:

✔1 ✘2 ✘3 ✘4 ✘5 
( It means he can only see the number of projects 
equivalent to his day_count ---- in case day_count not nil!)

例如:

  • 如果current_user的day_count = 1,那么他只能看到项目1:

    ✔1✘2✘3✘4✘5

  • 如果curent_user有day_count = 2,那么他只能看到项目1和2:

    ✔1✔2✘3✘4✘5

......依此类推,等等......

代码很简单,但非常重复。我知道这是一种糟糕的编码方式,但仍然无法弄清楚如何有效地减少它。如果我有超过30天,代码可以继续,继续超过2,000行代码,可能会使程序变慢!

任何人都可以帮我解决这个问题吗?提前谢谢。

2 个答案:

答案 0 :(得分:2)

路由

match 'projects/days/(:day)' => "projects#day", :via => [:get], as: "day"

视图

day.html.erb

<% if current_user.speed? || current_user.admin? %>
  "Display Day #{@day}"
<% else %>
<% unless current_user.day_count.nil? %>
  <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= @day %>
    "Display Day #{@day}"
  <% else %>
    "This project cannot open now. Please wait until day#{@day}!"
  <% end %>
<% end %>
  

控制器

def day
  @total_days = 5
  @day = params[:day]
end

的index.html

<% if current_user.speed? || current_user.admin? %>
  <div class="day_tracking">
    <% @total_days.each do |day| %>
    <div class="day_passed"><span>✔</span><p><%= day %></p></div>
  </div>
<% else %>
  <% unless current_user.day_count.nil? %>
    <div class="day_tracking">
      <% @total_days.each do |day| %>
        <% if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= day %>
          <div class="day_passed"><span>✔</span><p><%= day %></p></div>
        <% else %>
          <div class="day_left"><span>✘</span><p><%= day %></p></div>
        <% end %>
      <% end %>
    </div>  
  <% end %>
<% end %>

你可以这样。有更多的重构点,它只是概念。

答案 1 :(得分:0)

可以很容易地重新考虑。 Ruby的主要原则之一是DRY原则,你的设计与之相反。

根据此更改您的路线。

match 'projects/:days' => "projects#show_project", :via => [:get]

在你的控制器中你应该有这个。

def show_project
end

将业务逻辑转移到项目模型。

def has_access?(no_of_days)
  return true if current_user.speed? || current_user.admin?
  unless current_user.day_count.nil?
    if (Time.now.to_date - current_user.day_count.to_date).to_i + 1 >= no_of_days
      true
    else 
      false
  end
end

现在在你看来它就像。

一样简单
 <% if @project.has_access?(params[:days]) %>
   "Display Day #{params[:days]}"
 <% else %>
   "This project cannot open now. Please wait until day#{params[:days]}!"
 <% end %>