如何在Rails中选择数组中的属性?

时间:2016-05-19 02:07:04

标签: ruby-on-rails arrays postgresql activerecord

对于Rails,我是初学者,所以非常感谢任何帮助。以下是我的控制器查询的一部分:

def index
    @bookings = Booking.where(["end_at >= :endDate", { endDate: Date.today.to_s}])
    @ownerID = @bookings.collect{|booking| Player.select("user_id").where("booking_id = :bookingID", {bookingID: booking})}
end

这是我的观点的一部分,我正在尝试输出:

<tbody>
    <% @bookings.each_with_index do |booking, index| %>
    <tr>
        <td><%= booking.id %></td>
        <td><%= booking.court_id %></td>
        <td><%= @ownerID.values_at(index) %></td>
        <td><%= booking.start_at %> to <%= booking.end_at %></td>
        <td><%= booking.paid? ? 'Paid' : 'Not Paid' %></td>
        <td><%= link_to 'Cancel', edit_admin_court_path(booking) %></td>
    </tr>
    <% end %>
<tbody>

我正在从我的数据库中正确地收集值,但是我无法自己打印user_id的值。目前该列正在输出:

[#<ActiveRecord::Relation [#<Player id: nil, user_id: 4>]>]

但我只想要user_id中的4

我花了最后几个小时阅读阵列和AR,但我真的还不清楚它是否有意义。提前谢谢。

编辑:这是我预订的模型:     课程预订&lt;的ActiveRecord :: Base的     #e belongs_to:user     belongs_to:court     has_many:评论

has_many :players
has_many :users, through: :players

attr_accessor :day, :start_time, :end_time, :type_of_court

validates :start_at, :day, :start_time, :end_time, presence: true
validate :is_available?
validate :at_least_one_hour?

before_validation(on: :create) do
    self.key ||= SecureRandom.hex(5)

    if !day.blank?
        stime = Time.parse(start_time)
        self.start_at = Time.strptime(day, "%m-%d-%Y")+stime.hour.hours+stime.min.minutes
        etime = Time.parse(end_time)
        self.end_at = Time.strptime(day, "%m-%d-%Y")+etime.hour.hours+etime.min.minutes
    end

    self.half_court = type_of_court == 'Half Court'

    true
end

def at_least_one_hour?
    if !end_at.nil? && !start_at.nil?
        if (end_at - start_at) < 1.hour
            self.errors[:base] << "The booking is only available for periods of 1 hour or more"
        end
    end
end

def is_available?
    bookings = Booking.where('start_at BETWEEN (?) AND (?) or end_at BETWEEN (?) AND (?)', start_at, end_at, start_at, end_at)

    is_free = if bookings.count == 0
        true
    else
        bookings.first.end_at == start_at || bookings.first.start_at == end_at
    end

    # check if is available in court schedules
    if is_free
        booking_day_type = start_at.saturday? ? 'Saturday' : start_at.sunday? ? 'Sunday' : 'Weekday'

        schedule = court.schedules.where(day_type: booking_day_type).first

        if schedule.nil?
            is_free = false
        else
            start_at_hours, start_at_minutes =  schedule.start_at.split(':')
            end_at_hours, end_at_minutes =  schedule.end_at.split(':')

            schedule_start_at = Time.new start_at.year, start_at.month, start_at.day, start_at_hours, start_at_minutes, 0
            schedule_end_at = Time.new end_at.year, end_at.month, end_at.day, end_at_hours, end_at_minutes, 0

            is_free = (schedule_start_at..schedule_end_at).cover?(start_at) && (schedule_start_at..schedule_end_at).cover?(end_at)
        end
    end

    if !is_free
        self.errors[:base] << "The court isn't available on these hours"
    end

    return is_free
end

def owner
    owner = players.includes(:user).where(owner: true).first

    owner.user if owner
end

def by_admin?
    owner.nil? || owner.is_admin?
end

def court_type
    self.half_court ? 'Half Court' : 'Full Court'
end

def full_date
    "#{self.start_at.strftime('%d %b')}, #{self.time_date}"
end

def time_date
    "#{self.start_at.strftime('%I:%M')}-#{self.end_at.strftime('%I:%M')} #{self.start_at.strftime('%p')}"
end

def only_day_date
    "#{self.start_at.strftime('%b. %d')}"
end

def book_price
    price.nil? ? self.court.price : price
end
end

这是玩家的模型:

class Player < ActiveRecord::Base
  belongs_to :booking
  belongs_to :user
end

这是我的架构的一部分:

create_table "bookings", force: true do |t|
  t.integer  "court_id"
  t.datetime "start_at"
  t.datetime "end_at"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.boolean  "half_court", default: false
  t.float    "price"
  t.boolean  "paid"
  t.string   "key"
end

add_index "bookings", ["court_id"], name: "index_bookings_on_court_id", using: :btree
add_index "bookings", ["key"], name: "index_bookings_on_key", unique: true, using: :btree

create_table "players", force: true do |t|
  t.integer "booking_id"
  t.integer "user_id"
  t.boolean "owner",      default: false
end

add_index "players", ["booking_id"], name: "index_players_on_booking_id", using: :btree
add_index "players", ["user_id"], name: "index_players_on_user_id", using: :btree

1 个答案:

答案 0 :(得分:0)

你可以使用pluck,它会返回user_id的数组。

def index
  @bookings = Booking.where(["end_at >= :endDate", { endDate: Date.today.to_s}])
  @ownerID = @bookings.collect { |booking| Player.pluck(:user_id).where(booking_id: booking) }.flatten
end

您可以将代码简化为

def index
  @bookings = Booking.where("end_at >= ?", Date.today)
  @owner_ids = Player.where(booking_id: @bookings.map(:id)).pluck(:user_id)
end

似乎您的记录已关联。如果没有,您可以参考this并关联它们。所以你可以让这更简单。

控制器:

def index
  @bookings = Booking.includes(:players).where("end_at >= ?", Date.today)
end

查看:

<tbody>
    <% @bookings.each do |booking| %>
    <tr>
        <td><%= booking.id %></td>
        <td><%= booking.court_id %></td>
        <td><%= booking.players.map(&:user_id).join(', ') %></td>
        <td><%= booking.start_at %> to <%= booking.end_at %></td>
        <td><%= booking.paid? ? 'Paid' : 'Not Paid' %></td>
        <td><%= link_to 'Cancel', edit_admin_court_path(booking) %></td>
    </tr>
    <% end %>
<tbody>