【问题标题】:Proper method for time completion in Ruby on Rails在 Ruby on Rails 中完成时间的正确方法
【发布时间】:2015-02-10 14:18:35
【问题描述】:

我有一个评论部分,允许用户在他们的聚会后撰写对另一个用户的评论。我想允许用户在他们的聚会开始时间之后写评论。

我遇到的问题是,在创建两个用户之间的聚会后,立即允许用户在聚会开始时间之前为彼此撰写评论。我创建finished_meetup? 的方法一直都是正确的。我认为这是由于我的 start_time 显示错误。

在控制台中,如果我预订了晚上 8:30 的聚会,我会得到以下作为 start_time start_time: "2000-01-01 20:30:00" 的信息。日期附加到时间,不能删除,因为“Represent a time with no date in ruby”。

我将如何设置方法 finished_meetup? 以允许在聚会之后而不是事先进行评论。

shema.rb:

create_table "user_meetups", force: true do |t|
  t.integer  "user_id"
  t.integer  "friend_id"
  t.string   "state"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.date     "start_date"
  t.time     "start_time"

用户.rb

def find_corresponding_friend_id(friend_id)
  self.user_meetups.where(friend_id:friend_id).present?
end

def already_reviewed
  self.reviews.map{|d| d.review_writer_id}
end

def finished_meetup?
user_meetups.where("start_time < ?",  Time.new("2000/#{Time.now.strftime("%m/%d")}"))
end

用户/show.html.erb

<% if @user.find_corresponding_friend_id(current_user.id) && @user.already_reviewed.empty? && @user.finished_meetup? %>

user_meetup.rb

class UserMeetup < ActiveRecord::Base

    belongs_to :user
    belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'
    validates :start_date, :start_time, presence: true

    # attr_accessor :user, :friend, :user_id, :friend_id, :state

    after_destroy :delete_mutual_meetup!

    state_machine :state, initial: :pending do 

        after_transition on: :accept, do: [:accept_mutual_meetup!]

        after_transition on: :block, do: [:block_mutual_meetup!]

        after_transition on: :unblock, do: [:accept_mutual_meetup!]

        state :requested
        state :blocked

        event :accept do
            transition any => :accepted
        end

        event :block do
            transition any => :blocked
        end

        event :unblock do
            transition any => :accepted
        end
    end

    def self.request(start_date, start_time, location, description, learners, user1, user2)
        transaction do
            # Rails.logger.info "user1 is #{user1.inspect}"
            # Rails.logger.info "user2 is #{user2.inspect}"
            meetup1 = UserMeetup.create!(start_date: start_date, start_time: start_time, user: user1, friend: user2, state: 'pending')

            # Rails.logger.info "meetup1 is #{meetup1.inspect}"

            meetup2 = UserMeetup.create!(start_date: start_date, start_time: start_time, user: user2, friend: user1, state: 'requested' )

            # meetup1.send_request_email
            # meetup1
        end
    end

【问题讨论】:

  • 如果你有开始日期和开始时间,为什么要分开存储呢?为什么没有t.datetime 'start_at'?然后您可以将其与当前日期时间进行比较以了解是否允许。
  • 因为没办法,只能这样,查看链接stackoverflow.com/questions/6359978/…
  • 我明白了,我自己也遇到过这个问题,但我认为我在您的数据模型中遗漏了一些东西。那么start_datestart_time 彼此不相关吗?明天下午 4 点(忽略时区)举行的聚会是否会在表中获得一个条目,其中start_date 设置为2014-12-12,start_time 设置为16:00
  • 如果我在 12 月 9 日下午 6 点在控制台中进行聚会,它看起来像 start_date: "2014-12-09", start_time: "2000-01-01 18:00:00"
  • 为什么?!这是没有意义的。在任何情况下,无论你如何存储东西,你都可以随心所欲地对其进行操作。

标签: ruby postgresql date time strftime


【解决方案1】:

此方法将返回当前时间之前开始的用户聚会列表

def finished_meetup
  self.user_meetups.where("start_time < ?",  Time.now.to_s.gsub(/#{Date.today.to_s}/, '2000-01-01'))
end

【讨论】:

    【解决方案2】:

    你的所作所为不是真假。它将返回一个数组或空数组。两者都不是错误的。

    尝试使用“空?”

    def finished_meetup?
      !self.finished_meetups.empty?
    end
    

    这实质上是在询问finished_meetups 是否不为空。

    【讨论】:

      【解决方案3】:

      您的日期/时间分离使事情变得复杂。将您的 start_timestart_date 更改为 start_at datetime 列。迁移将如下所示:

      class SomeMigrationClass < ActiveRecord:Migration
        def change
          add_column :user_meetups, :start_at, :datetime
          UserMeetups.find_in_batches.each do |um|
            d = um.start_date
            t = um.start_time
            dt = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
            um.update!(start_at: dt)
          end
          remove_columns :user_meetups, :start_time, :start_date
        end
      end
      

      这应该保留您拥有的任何现有数据并将它们组合成日期时间。当然未经测试,如果你有生产数据测试测试测试!

      接下来,只需将该日期时间与当前日期进行比较。

      def finished_meetups
        self.user_meetups.where('start_at < ?', Time.current)
      end
      

      这将返回在当前时间之前发生start_at 次的用户聚会。

      如果您真的想要关于是否有任何已完成的聚会的布尔响应,您可以在此基础上构建:

      def finished_meetup?
        self.finished_meetups.any?
      end
      

      【讨论】:

      • 在迁移过程中显示“LocalJumpError: no block given (yield)”
      • 可能是 do/end 块中的错字。没有行号或更多细节无法确定。上面的迁移是一个起点。如果您没有要迁移的宝贵数据,请放弃数据转换部分。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多