2012-03-05 2 views
1

У меня есть сложная проблема, над которой я работаю в своем текущем приложении rails. В моих приложениях пользователи обмениваются фотографиями. Фотографии могут быть связаны с городом, поэтому City has_many :photos. Я хочу, чтобы пользователи могли связывать свои фотографии с городом с использованием автозаполнения и синтаксиса на естественном языке. Т.е.: Нью-Йорк, Нью-Йорк или Париж, Франция.Rails: Найти или создать по виртуальному атрибуту

Я хотел бы сделать это с помощью автозаполнения текстового поля так, что если пользователь «Афины» они будут видеть список с:

Athens, Greece 
Athens, GA 

... и если человек на самом деле хотел «Афины , TX "они могли бы просто напечатать это, и он создаст новую городскую запись.

Моя городская модель имеет поля, name, state, country. Государство и страна - это двухбуквенные почтовые индексы (я использую Carmen для их проверки). У меня есть виртуальный атрибут под названием 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, который может принимать строку с названием города и либо государственного кода или название страны и найти или создать эту запись?


Update

Вдохновленный ответ 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 

Это качалки мои спецификации прямо сейчас, так что я думаю, что моя проблема решена ,

ответ

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") 
) 
+0

Это не * точно *, что я искал, но вы вдохновили меня, и я думаю, что я нашел приемлемое решение. Я добавлю его к вопросу для справки. – Andrew

Смежные вопросы