0

我的应用程序在时间表索引中显示 user.name 时遇到问题(显示所有时间表,而不仅仅是当前用户时间表)

用户型号:

# Table name: timesheets
#
#  id         :integer         not null, primary key
#  user_id    :integer
#  starting   :datetime
#  ending     :datetime
#  approved   :boolean
#  created_at :datetime        not null
#  updated_at :datetime        not null
#

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password
  has_many :timesheets
  ....
end

时间表模型(标准 user_id 是外键)

# Table name: timesheets
#
#  id         :integer         not null, primary key
#  user_id    :integer
#  starting   :datetime 
#  ending     :datetime
#  approved   :boolean
#  created_at :datetime        not null
#  updated_at :datetime        not null
#

class Timesheet < ActiveRecord::Base
  attr_accessible :starting, :ending
  belongs_to :user

  validates :user_id, presence: true
  validates :starting, presence: true
  validates :ending, presence: true
  validate :end_after_start
...
end

我的时间表控制器中的索引定义:

def index
  @timesheets = Timesheet.paginate(page: params[:page], per_page: 10)
end

最后是显示 user_id 的 index.html.erb 文件,但我想要的是用户名。请记住,这是由管理员批准时间表,因此不会是登录用户,而是希望查看所有时间表并批准他们想要的时间表的管理员。

<ul class="timesheets">
<% @timesheets.each do |timesheet| %>
    <NOBR>
    <li>
          <%= timesheet.user_id %>
          <%= timesheet.starting.strftime("[ %^a %^b %e,  %Y - %l:%M %p ] - ") %><%= timesheet.ending.strftime("[ %^a %^b %e,  %Y - %l:%M %p ]") %> <%= (timesheet.ending - timesheet.starting)/3600 %> Hours
          <% if current_user.admin? %>
                |
              <% if timesheet.approved? %>
                 <%= link_to "Un-Approve", { action: :unapprove, id: timesheet.id }, method: :put %>
              <% else %>
                 <%= link_to "Approve", { action: :approve, id: timesheet.id }, method: :put %>
              <% end %> 
         <% end %>
        </li>
    </NOBR>
<% end %>
</ul>

<%= will_paginate %>

非常感谢您的帮助,这是我提出的第一个问题,所以我希望我遵循了所有正确的协议。

4

2 回答 2

2

根据“ RAILS ANTIPATTERNS - Ruby on Rails 重构最佳实践

Ruby on Rails 使您可以轻松地在对象之间的关系之间导航,因此可以轻松地深入了解相关对象并跨相关对象进行深入研究。根据 Rails 中的 Demeter 法则,在对象关系之间导航时“只使用一个点”。例如,@category.product.name违反了得墨忒耳法则,但 @ category.product_name没有。

因此,获取时间表用户名的最佳方法是,您应该使用

timesheet.user_name

代替

timesheet.user.name

为此,只需将具有所需属性的委托方法添加到 Timesheet 模型中,如下所示

delegate :name, :email, to: :user, :prefix => true

所以你的模型将是

class Timesheet < ActiveRecord::Base
  attr_accessible :starting, :ending
  belongs_to :user

  validates :user_id, presence: true
  validates :starting, presence: true
  validates :ending, presence: true
  validate :end_after_start

  delegate :name, :email, to: :user, :prefix => true

  ...

end

现在,通过调用获取视图文件中的用户名

timesheet.user_name

像这样,您还可以获得用户电子邮件,如下所示

timesheet.user_email
于 2013-08-13T06:31:18.277 回答
1

如果您与用户模型有关联,那么您可以通过调用来获取用户模型

timesheet.user

在这个问题的这种情况下

<ul class="timesheets">
<% @timesheets.each do |timesheet| %>
    <NOBR>
    <li>
          <%= timesheet.user.name %>
          <%= timesheet.starting.strftime("[ %^a %^b %e,  %Y - %l:%M %p ] - ") %><%= timesheet.ending.strftime("[ %^a %^b %e,  %Y - %l:%M %p ]") %> <%= (timesheet.ending - timesheet.starting)/3600 %> Hours
          <% if current_user.admin? %>
                |
              <% if timesheet.approved? %>
                 <%= link_to "Un-Approve", { action: :unapprove, id: timesheet.id }, method: :put %>
              <% else %>
                 <%= link_to "Approve", { action: :approve, id: timesheet.id }, method: :put %>
              <% end %> 
         <% end %>
        </li>
    </NOBR>
<% end %>
</ul>

<%= will_paginate %>
于 2013-08-13T03:57:06.373 回答