【问题标题】:How to set timestamp from home page?如何从主页设置时间戳?
【发布时间】:2015-07-19 22:58:58
【问题描述】:

我们如何从主页设置:completed_at时间戳?

[2] pry(main)> Habit.find(18)
 id: 1,
 missed_days: 0,
 conceal: false,
 committed: ["tue", "wed", "thu", "fri", ""],
 date_started: Wed, 22 Jul 2015 00:00:00 EDT -04:00,
 action: "test",
 user_id: 1,
 created_at: Wed, 22 Jul 2015 17:37:59 EDT -04:00,
 updated_at: Wed, 22 Jul 2015 17:38:01 EDT -04:00,
 completed_at: nil,

控制器

def home
  @habits = current_user.habits.committed_for_today.incomplete.order(:order)
end

通过设置:completed_at,模型会让控制器知道习惯已经完成(也就是不再incomplete

habit.rb

class Habit < ActiveRecord::Base
    belongs_to :user
    has_many :levels, -> { order(:id) }
    serialize :committed, Array
    before_save :current_level
    attr_accessor :missed_one, :missed_two, :missed_three
   scope :incomplete, -> { where(completed_at: nil) }

    def completed=(boolean)
      self.completed_at = boolean ? Time.current : nil
    end

    def completed
      completed_at && completed_at >= Time.current.beginning_of_day
    end

    def self.committed_for_today
      today_name = Date::ABBR_DAYNAMES[Date.today.wday].downcase
      ids = all.select { |h| h.committed.include? today_name }.map(&:id)
      where(id: ids)
    end 

    def save_with_current_level
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.levels.build
        self.save
    end

    def current_level_strike
      levels[current_level - 1] # remember arrays indexes start at 0
    end

    def current_level
            return 0 unless date_started
          def committed_wdays
            committed.map do |day|    
              Date::ABBR_DAYNAMES.index(day.titleize)
            end
          end

          def n_days
            ((date_started.to_date)..Date.yesterday).count do |date| 
              committed_wdays.include? date.wday
            end - self.real_missed_days
          end     

      case n_days     
          when 0..9
            1
          when 10..24
            2
          when 25..44
            3
          when 45..69
            4
          when 70..99
            5
          else
            6
        end
    end

 def real_missed_days
     value = 0
     levels.each do |level|
         value += level.missed_days + level.days_lost
     end
     value
  end

  def calculate_days_lost
      def n_days
        ((date_started.to_date)..Date.yesterday).count do |date| 
          committed_wdays.include? date.wday
        end - self.real_missed_days
      end     

   case n_days    
      when 0..9
        n_days
      when 10..24
        n_days-10
      when 25..44
        n_days-25
      when 45..69
        n_days-45
      when 70..99
        n_days-70
      else
        n_days-100
    end
  end

    def days_left_in_current_level
        def n_days
            ((date_started.to_date)..Date.yesterday).count do |date|
                committed_wdays.include? date.wday
            end - self.real_missed_days
        end

        case n_days
          when 0..9
            10-n_days
          when 10..24
            25-n_days
          when 25..44
            45-n_days
          when 45..69
            70-n_days
          when 70..99
            100-n_days
          else
            0 # No end
        end
    end
end

我想用link_tobutton_tag 触发:completed_at。然后,一旦单击其中一项并设置了:completed_at,则主页应以redirect_to root_url 刷新,现在已删除:completed_at 习惯,因为主页仅显示incomplete 习惯。

这是它的Gist

【问题讨论】:

  • 什么控制器方法将习惯标记为完成?注意link_to中的methodhas to be a valid HTTP verb
  • 是的,@AbM 我只是以它为例。我试图弄清楚如果有什么要放在控制器中,以及如何重写视图代码

标签: ruby-on-rails ruby model-view-controller


【解决方案1】:

我更喜欢这种 Ajax 方式。

在你看来

#home view page

<table>
<% @habits.each do |habit| %>
<tr>
<td><%= link_to "Mark Completed", mark_completed_path(habit), remote: true, method: 'put', class: 'update_habit' %></td>
</tr>
<% end %>
</table>

<script>
$('.update_habbit').bind('ajax:success', function() {
$(this).closest('tr').fadeOut();
});
</script>

如果要删除,请将script 更改为

<script>
$('.update_habbit').bind('ajax:success', function() {
$(this).closest('tr').remove();
});
</script>

制定路线

#routes.rb
put '/mark_completed/:id', to: 'habits#mark_completed', as: 'mark_completed'

在你的HabbitsController 中创建一个方法

def mark_completed
@habit = Habit.find(params[:id])
@habit.update(completed_at: Time.now)

  respond_to do |format|
    format.html
    format.js { render :nothing => true }
  end
end

【讨论】:

  • 谢谢 Pavan 我认为这可能是最好的答案 :) 但我不认为 AJAX 无法正常工作。当我点击mark_completed 时,AJAX 会触发,但除非我刷新页面,否则习惯不会fadeOut 或得到removed。我认为 AJAX 的想法是让我们不必刷新页面。
  • @AnthonyGalli.com 您是否将其包含在 &lt;tr&gt;&lt;/tr&gt; 中?我的回答特别与&lt;tr&gt;有关。
  • 是的,即使我删除了我的主页视图部分(页面/_习惯)中的所有内容,只需将您的代码复制并粘贴到其中。
  • @AnthonyGalli.com 您的链接是否与我的回答一样正确?
  • 哇终于明白了帕万哈哈毕竟这是因为你在.update_habbit中放了两个bb。我应该早点发现的:/但是和你一起走过很有趣。我是这样学的:]
【解决方案2】:

您可以创建HabitsController#complete 操作,并使用表单发送请求。由于您没有分享您的观点,我假设您有一个 habit 变量,其中包含您要完成的对象。

<%= button_to 'Complete', complete_habit_path(habit) %>

动作代码:

def complete
  habit = Habit.find(params[:id])
  habit.complete = true
  habit.save
  # or habit.update(completed_at: Time.current)
  redirect_to root_url
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2021-07-14
    • 2015-08-28
    相关资源
    最近更新 更多