Правильный метод завершения времени в Ruby on Rails

У меня есть раздел отзывов, который позволяет пользователю написать отзыв о другом пользователе после их встречи. Я хочу разрешить пользователям писать обзоры после start_time их встречи.

Проблема, с которой я сталкиваюсь, заключается в том, что сразу после создания встречи между двумя пользователями пользователям разрешается писать обзоры друг для друга до начала их встречи. Метод, который я создал finished_meetup?, все время читается как true. Я думаю, это связано с тем, что мое start_time отображается неправильно.

В консоли, если я бронирую встречу на 20:30, я получаю следующее как start_time start_time: "2000-01-01 20:30:00". Дата привязана ко времени и не может быть удалена, потому что "представляет время без дата рубиновым шрифтом".

Как мне настроить метод finished_meetup?, чтобы обзоры проводились после встречи, а не заранее.

схема.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

person achilles77    schedule 11.12.2014    source источник
comment
Если у вас есть дата начала и время начала, почему вы храните их отдельно? Почему бы не t.datetime 'start_at'? Затем вы можете просто сравнить его с текущей датой и временем, чтобы узнать, разрешено ли это.   -  person Nick Veys    schedule 12.12.2014
comment
Поскольку у меня нет другого выбора, кроме как сделать это так, проверьте заголовок ссылки stackoverflow.com/questions/6359978/   -  person achilles77    schedule 12.12.2014
comment
Я вижу это, я сам столкнулся с этой проблемой, но я думаю, что что-то упускаю из вашей модели данных. Значит, start_date и start_time не связаны друг с другом? Получает ли встреча, которая состоится завтра в 16:00 (без учета часовых поясов), запись в таблице с start_date, установленным на 2014-12-12, и start_time на 16:00?   -  person Nick Veys    schedule 12.12.2014
comment
Если бы я проводил встречу 9 декабря в 18:00 в консоли, это выглядело бы как start_date: 2014-12-09, start_time: 2000-01-01 18:00:00   -  person achilles77    schedule 12.12.2014
comment
Почему?! Это бессмысленно. В любом случае, независимо от того, как вы что-то храните, вы можете работать с этим, как хотите.   -  person Dave Newton    schedule 12.12.2014
comment
Потому что мне нужен отдельный слот для времени и даты. Если бы вам нужно было работать с ним, чтобы после него можно было просмотреть встречу, как бы вы написали метод?   -  person achilles77    schedule 12.12.2014
comment
Я не вижу вашей потребности в отдельном времени и дате, вам нужна дата и время, время не зависит от даты, это ее часть. Я опубликую ответ с лучшей информацией.   -  person Nick Veys    schedule 12.12.2014
comment
Должен ли finished_meetup? возвращать true/false? Или вы пытаетесь собрать коллекцию готовых митапов? Вот такая логика...   -  person Nick Veys    schedule 12.12.2014
comment
Предполагается, что он возвращает true или false. Я изменил Finish_meetup? логика. просто пытаюсь разрешить пользователям просматривать встречу после того, как прошло start_time и start_date   -  person achilles77    schedule 12.12.2014
comment
Таким образом, метод должен возвращать информацию о том, есть ли у пользователя завершенные какие-либо встречи? Прямо сейчас у вас есть запросы на завершенные встречи.   -  person Nick Veys    schedule 12.12.2014


Ответы (3)


этот метод вернет список встреч пользователей, начатых до текущего времени

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

Ваше разделение даты и времени усложняет ситуацию. Измените столбцы start_time и start_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
person Nick Veys    schedule 12.12.2014
comment
во время миграции он говорит LocalJumpError: блок не указан (выход) - person achilles77; 12.12.2014
comment
Вероятно, опечатка в блоке do/end. Без номеров строк или более подробной информации нельзя быть уверенным. Описанная выше миграция предназначена в качестве отправной точки. Если у вас нет ценных данных для переноса, откажитесь от части преобразования данных. - person Nick Veys; 12.12.2014

То, что вы сделали, не является истинным или ложным случаем. Он либо вернет массив, либо пустой массив. Ни одно из них никогда не является ложным.

Попробуйте использовать «пустой?»

def finished_meetup?
  !self.finished_meetups.empty?
end

По сути, это вопрос о том, НЕ пусто ли значение finish_meetups.

person Steffan Perry    schedule 12.12.2014