在 Rails 4 中使用虚拟属性计算和显示日期

Posted

技术标签:

【中文标题】在 Rails 4 中使用虚拟属性计算和显示日期【英文标题】:Calculate And Display A Date Using A Virtual Attribute in Rails 4 【发布时间】:2017-10-05 20:44:36 【问题描述】:

我正在尝试使用 Rails 中的虚拟属性计算和显示日期。我有一个模型,Group,每个 Group 都有几个 GroupMeetings。还有一个 GroupDates 表存储每个组的第一个开始日期(管理员通过表单提交)以及时区。小组会面数周,由管理员决定。

由于 GroupDates 表已经存在,我想使用开始日期和周数计算每个会议日期,而不将日期保存在 GroupMeetings 表中。我正在尝试使用虚拟属性来保存会议日期并显示它,但它显然不会持久。有没有办法不将会议日期保存在 GroupMeeting 的列中?

在我的模型中,我选择了一个组的所有 GroupMeetings(当管理员将一个组标记为活动时创建)并尝试迭代,将第一次会议的日期与组开始日期相同,随后的每个会议上一次会议之后的会议+ 7.days。在一个视图中,我遍历每个 GroupMeeting 以在编辑表单中显示字段,以便主持人可以更新会议主题和注释。我想在每个主题字段上方显示会议日期。

小组会议模式:

class GroupMeeting < ActiveRecord::Base
  belongs_to :group
  has_many :users, through: :group, as: :group_users

  validates :group, presence: true

  attr_accessor :meeting_date

  def generate_meeting_date
    @meetings = GroupMeeting.where(group_id: self.group_id).order('id ASC')

    @meetings.each_with_index do |meeting, index|
      if self == @meetings.first
        self.meeting_date = self.group.start_date
      else
        previous = @meetings[index-1]
        self.meeting_date = previous.meeting_date + 7.days
      end
    end

     return self.meeting_date.strftime("%a %b%e, %Y at %k%p")
  end

end

相关查看/编辑表单:

<% @group_meetings.each do |meeting| %>
 <%= fields_for 'meetings[]', meeting do |m| %>
  <div class="field">
    <strong><%= meeting.generate_meeting_date %></strong>
    <%= m.text_field :topic, label: false %>
  </div>
  <div class="field">
    <%= m.text_field :notes, label: false %>
 </div>
<% end %>

【问题讨论】:

【参考方案1】:

我认为你在正确的轨道上,只是缺少一个属性。您也可以为您的实例方法创建一个虚拟属性,这应该可以解决它。

class GroupMeeting < ActiveRecord::Base
  belongs_to :group
  has_many :users, through: :group, as: :group_users

  validates :group, presence: true

  attr_accessor :meeting_date, :generate_meeting_date

  def generate_meeting_date
    @meetings = GroupMeeting.where(group_id: self.group_id).order('id ASC')

    @meetings.each_with_index do |meeting, index|
      if self == @meetings.first
        self.meeting_date = self.group.start_date
      else
        previous = @meetings[index-1]
        self.meeting_date = previous.meeting_date + 7.days
      end
    end

     return self.meeting_date.strftime("%a %b%e, %Y at %k%p")
  end

end

虽然,为了在 UI 中显示值,我可能会考虑在您的类上使用帮助程序而不是实例方法。

【讨论】:

关于辅助方法与类方法的优点。将尝试使用附加属性。谢谢!

以上是关于在 Rails 4 中使用虚拟属性计算和显示日期的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 - 将日期时间转换为单独的日期和时间字段

rails-如何根据时间/日期更新属性

vue计算属性computed和监视器watch的使用

在另一个模型控制器中使用的 Rails 3 虚拟属性

使用 Rails 4.2 和 lograge,如何在每个记录的行之前启用日期/时间?

日期时间:以小时计的小时数