nil:NilClass 的自定义 slug 的未定义方法“名称”
undefined method `name' for nil:NilClass for custom slug
我有一个 Restaurant
模型,它使用 Geocoder 在 before_validation
回调中收集城市、州和社区。
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
在我的 City
模型中,我组合了一个自定义 slug,它使用城市名称和它所属的州名称。
class City < ActiveRecord::Base
# attrs :name, state_id
belongs_to :state
friendly_id :state_slug, use: :slugged
def state_slug
"#{name} #{state.name}"
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
我能想到的唯一方法是使用inverse_of
:
#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
关于这个的文档不多;它基本上意味着您可以在各自的模型中调用关联数据,IE city.state
(即使未保存 state
)。
因此,如果您在每次添加城市(并且它们是相关联的)时设置一个 状态 ,您 应该 能够调用以下 (validation
):
#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
我有一个 Restaurant
模型,它使用 Geocoder 在 before_validation
回调中收集城市、州和社区。
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
在我的 City
模型中,我组合了一个自定义 slug,它使用城市名称和它所属的州名称。
class City < ActiveRecord::Base
# attrs :name, state_id
belongs_to :state
friendly_id :state_slug, use: :slugged
def state_slug
"#{name} #{state.name}"
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
我能想到的唯一方法是使用inverse_of
:
#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
关于这个的文档不多;它基本上意味着您可以在各自的模型中调用关联数据,IE city.state
(即使未保存 state
)。
因此,如果您在每次添加城市(并且它们是相关联的)时设置一个 状态 ,您 应该 能够调用以下 (validation
):
#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