0

I have a review section which allows a user to write a review of another user following their meetup. I want to permit users to write a review following the start_time of their meetup.

The problem I am having is, immediately upon a meetup between two users being created the users are allowed to write a review for one another before their meetup start_time. The method I created finished_meetup? is reading true all the time. I think this is due to my start_time being displayed wrong.

In the console, if I book a meetup for 8:30pm I get the following as the start_time start_time: "2000-01-01 20:30:00". Date is attached to time and cannot be eliminated because "Represent a time with no date in ruby".

How would I set up the method finished_meetup? to allow for the reviews to be done following the meetup and not beforehand.

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"

user.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

users/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
Community
  • 1
  • 1
achilles77
  • 325
  • 2
  • 3
  • 11
  • 1
    If you have a start date and start time, why are you storing them separately? Why not have `t.datetime 'start_at'`? Then you could just compare it to the current datetime to know if it is allowed. – Nick Veys Dec 11 '14 at 23:05
  • Because I have no choice but to do it like that, check out the link http://stackoverflow.com/questions/6359978/represent-a-time-with-no-date-in-ruby – achilles77 Dec 11 '14 at 23:07
  • I see that, I've run into that issue myself, but I think I'm missing something with your data model. So the `start_date` and `start_time` aren't related to each other? Does a meetup that happens tomorrow at 4pm (ignoring time zones) get an entry in the table with `start_date` set to `2014-12-12` and a start_time to `16:00`? – Nick Veys Dec 11 '14 at 23:19
  • If I was doing a meetup on December 9 at 6pm in the console it would look like start_date: "2014-12-09", start_time: "2000-01-01 18:00:00" – achilles77 Dec 11 '14 at 23:29
  • Why?! That makes no sense. In any case, regardless of how you're storing something, you can operate on it however you want. – Dave Newton Dec 11 '14 at 23:36
  • Because I need a separate slot for time and date. If you were to operate on it to allow for the meetup to be reviewed after, how would you write the method? – achilles77 Dec 11 '14 at 23:56
  • I'm not seeing your need for a separate time and date, you need a datetime, the time is not independent of the date, it's part of it. I'll post an answer with better info. – Nick Veys Dec 12 '14 at 00:14
  • Is the `finished_meetup?` supposed to return a true/false? Or are you trying to get a collection of "finished" meetups? That's what the logic looks like... – Nick Veys Dec 12 '14 at 00:22
  • Its supposed to return true or false. I changed the finished_meetup? logic. just trying to allow users to review a meetup after start_time and start_date has passed – achilles77 Dec 12 '14 at 00:26
  • So the method should return whether the user has *any* meetups that are finished? Right now what you have is querying for meetups that are finished. – Nick Veys Dec 12 '14 at 00:29

3 Answers3

0

this method will return the list of user meetups started before the current time

def finished_meetup
  self.user_meetups.where("start_time < ?",  Time.now.to_s.gsub(/#{Date.today.to_s}/, '2000-01-01'))
end
Abdoo Dev
  • 1,216
  • 11
  • 16
0

What you have done is not a true or false case. It will either return an array or and empty array. Neither of which are ever false.

Try using "empty?"

def finished_meetup?
  !self.finished_meetups.empty?
end

This is essentially asking if finished_meetups is NOT empty.

Steffan Perry
  • 2,112
  • 1
  • 21
  • 21
0

Your date/time separation is complicating things. Change your start_time and start_date to a start_at datetime column. The migration will look something like this:

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

This should preserve any existing data you have and combine them into datetimes. Untested of course, if you have production data test test test!

Next, just compare that datetime with the current date.

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

This will return the user's meetups that have start_at times occurring before the current time.

If you really want a boolean response on whether there are any finished meetups, you could build on this with:

def finished_meetup?
  self.finished_meetups.any?
end
Nick Veys
  • 23,458
  • 4
  • 47
  • 64
  • during the migration it says "LocalJumpError: no block given (yield)" – achilles77 Dec 12 '14 at 00:44
  • Probably a typo in the do/end block. Without line numbers or more details can't be sure. The migration above is meant as a starting point. If you don't have precious data to migrate ditch the data conversion portion. – Nick Veys Dec 12 '14 at 01:15