Rails:通过虚拟属性查找或创建

时间:2012-03-05 23:26:09

标签: ruby-on-rails virtual-attribute

我有一个棘手的问题,我正在使用当前的rails应用程序。在我的应用中,用户分享照片。照片可以与城市相关联,因此City has_many :photos。我希望用户能够使用自动填充和自然语言语法将他们的照片与城市相关联。即:纽约,纽约或法国巴黎。

我想使用自动填充文本框执行此操作,以便在用户键入“Athens”时,他们会看到一个列表:

Athens, Greece
Athens, GA

......如果这个人真的想要“雅典,德克萨斯”,他们可以简单地输入,这将创造一个新的城市记录。

我的城市模型包含字段name, state, country。州和国家是2个字母的邮政编码(我使用卡门来验证它们)。我有一个名为full_name的虚拟属性,它为北美城市返回“城市,州代码”(如纽约,纽约),为所有其他城市返回“城市,国家名称”(如巴黎,法国)。

def full_name
    if north_american?
        [name, state].join(', ')
    else
        [name, Carmen.country_name( country )].join(', ')
    end
end

def north_american?
    ['US','CA'].include? country
end

我的问题是,为了使文本字段正常工作,如何创建一个find_or_create方法,该方法可以接受带有城市名称和州代码或国家/地区名称的字符串,并查找或创建该记录?


更新

受到Kandada答案的启发,我想出了一些不同的东西:

def self.find_or_create_by_location_string( string )
  city,second = string.split(',').map(&:strip)
  if second.length == 2
    country = self.country_for_state( second )
    self.find_or_create_by_name_and_state( city, second.upcase, :country => country )
  else
    country = Carmen.country_code(second)
    self.find_or_create_by_name_and_country( city, country )
  end
end

def self.country_for_state( state )
  if Carmen.state_codes('US').include? state
    'US'
  elsif Carmen.state_codes('CA').include? state
    'CA'
  else
    nil
  end
end

这正在震撼我的规格,所以我认为我的问题已经解决了。

1 个答案:

答案 0 :(得分:2)

class Photo < ActiveRecord::Base

  attr_accessor :location

  def self.location_hash location
    city,state,country = location.split(",")
    country = "US" if country.blank?
    {:city => city, :state => state,  :country => :country}
  end

end

现在你可以'find_or_create_by _ *'

Photo.find_or_create_by_name(
  Photo.location_hash(location).merge(:name => "foor bar")
)