尝试访问另一个模型的属性时出现NoMethodError

时间:2013-10-25 16:04:11

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

我在理解为什么我无法使用包装器方法访问Rails中的关联模型的属性时遇到了一些麻烦。我有一个模型规格失败,这是一个例子:

enter image description here

以下是相关文件的简短说明列表:

event.rb

class Event < ActiveRecord::Base
  attr_accessible :author, :away_team_score, :details, :event_on, 
                  :home_team_score, :name, :title, :type, :home_team_id,
                  :away_team_id, :winner, :user_id

  validates_presence_of :author, :name, :title, :event_on, :type

  has_many :articles, dependent: :destroy
  has_many :medias, dependent: :destroy

  belongs_to :user
  belongs_to :home_team, class_name: "Team"
  belongs_to :away_team, class_name: "Team"

  scope :by_user, ->(user_id) {where(user_id: user_id).order("name")}
  scope :by_team, ->(team_id) {where(team_id: team_id).order("sport_type")}
  scope :by_score, -> {select(:home_team_score, :away_team_score, :winner)}
  scope :upcoming_events, -> {where("event_on >= ?", 1.minute.from_now)}
  scope :past_events, -> {where("event_on < ?", 1.minute.ago)}
  scope :recent, -> {where("event_on > ?", 3.days.ago).limit(3)}

  def winner
    if home_team_score > away_team_score
      home_team_name
    elsif home_team_score == away_team_score
      "#{home_team_name} #{away_team_name}"
    else
      away_team_name
    end
  end

  private
  def home_team_name
    home_team.name
  end

  def away_team_name
    away_team.name
  end
end

team.rb

class Team < ActiveRecord::Base
  attr_accessible :name, :sport_type, :university_id

  belongs_to :university

  validates_presence_of :name, :sport_type
end


event_spec.rb - only the failing spec.

context "a winning home team" do
  it "returns the home team name" do
    event = Event.new
    event.home_team_score = 20
    event.away_team_score = 10
    expect(event.winner).to eq event.home_team_name
  end
end

提前致谢!

2 个答案:

答案 0 :(得分:1)

您可以使用my_object.try(:方法):如果my_object为nil,则不会引发错误

def home_team_name
  home_team.try(:name)
end

def away_team_name
  away_team.try(:name)
end

如果您想在没有离开/主队的情况下显示值,请使用双重管道:

def away_team_name
  away_team.try(:name) || 'No away team associated'
end

另一种选择,更明确:

def away_team_name
  if away_team.present?
    away_team.name
  else
    'No away team associated'
  end
end

或简短版本:

def away_team_name
  away_team.present? ? away_team.name : 'No away team associated'
end

答案 1 :(得分:1)

在您的规范中,您没有在活动和团队之间建立关联。您致电Event.new以获取新活动,但之后永远不会在event与任何团队之间建立关联。因此,当然,home_teamaway_team在该事件实例上都是nil。

您需要在规范中进行更好的设置。

it "returns the home team name"  
  event = Event.new(home_team_score: 20, away_team_score: 10)
  event.home_team = Team.new(name: 'foo')
  expect(event.winner).to eq 'foo'
end