Ruby on rails 未定义的方法`name';对于nil:NilClass用于定制slug

Ruby on rails 未定义的方法`name';对于nil:NilClass用于定制slug,ruby-on-rails,associations,geocoding,slug,friendly-id,Ruby On Rails,Associations,Geocoding,Slug,Friendly Id,我有一个餐厅模型,它使用地理编码器在验证回调之前在上收集城市、州和社区 class Restaurant < ActiveRecord::Base # attrs: :name, :address, :city_id, :neighborhood_id ... before_validation :geocode geocoded_by :address do |obj,results| if geo = results.first obj.cit

我有一个
餐厅
模型,它使用地理编码器在验证回调之前在
上收集城市、州和社区

class Restaurant < ActiveRecord::Base
  # attrs: :name, :address, :city_id, :neighborhood_id

  ...

  before_validation :geocode

  geocoded_by :address do |obj,results|
    if geo = results.first
      obj.city = City.where(name: geo.city).first_or_create
      obj.city.update_attributes(state: State.where(name: geo.state).first_or_create)

      obj.neighborhood = Neighborhood.where(name: geo.neighborhood).first_or_create
      obj.neighborhood.update_attributes(city: City.where(name: geo.city).first_or_create)

      obj.longitude = geo.longitude
      obj.latitude = geo.latitude
    end
  end
end
每当我创建一家新餐厅时,我都会犯错误:

undefined method `name' for nil:NilClass

def state_slug
  "#{name} #{state.name}"
end

这是可以理解的,因为没有一个城市或州尚未被持久化到数据库中。我想知道如何配置回调以使其工作?

在您的城市模型中编写此方法。当您的状态id更改时,这将生成slug

def should_generate_new_friendly_id?
    new_record? || state_id_changed?
end
对下面的方法做一点小小的改变

  def state_slug
   "#{name} #{state.name}" if state.present?
  end

我能想到的唯一方法是使用:


你试过了吗<代码>“{name}{city.try(:name)}”
?它将确保当
city
nil
时不会失败是的,但问题是我需要城市的名称。按照你所说的做会给我带来
/houston
,而不是
/houston texas
。我需要两个中的后一个。你需要州的名字,而不是城市的名字。这将由friendly在你创建、签出第一个条件新记录时负责?。这将使这一切发生。在遵循我的解决方案时,您是否遇到任何问题?让我知道我可以分享。这件事可以用很多方法来做。看来的逆运算并没有奏效。仍然留下同样的错误。
  def state_slug
   "#{name} #{state.name}" if state.present?
  end
#app/models/state.rb
class State < ActiveRecord::Base
   has_many :cities, inverse_of: :state
end

#app/models/city.rb
class City < ActiveRecord::Base
  belongs_to :state, inverse_of: :cities
end
#app/models/city.rb
class City < ActiveRecord::Base
   belongs_to :state, inverse_of: :cities
   validates :state, presence: true

   friendly_id :state_slug, use: :slugged

   private

   def state_slug
     "#{name} #{state.name}"
   end
end