2012-03-05 4 views
1

J'ai un problème délicat sur lequel je travaille dans mon application rails actuelle. Dans mon application, les utilisateurs partagent des photos. Les photos peuvent être associées à une ville, donc City has_many :photos. Je souhaite que les utilisateurs puissent associer leurs photos à une ville en utilisant la saisie semi-automatique et une syntaxe en langage naturel. C'est à dire: New York, NY ou Paris, France.Rails: Trouver ou créer par attribut virtuel

Je voudrais le faire avec une zone de texte de saisie semi-automatique de sorte que si les types d'utilisateurs « Athènes », ils verraient une liste avec:

Athens, Greece 
Athens, GA 

... et si la personne voulait vraiment « Athènes , TX "ils pourraient simplement taper cela et créer un nouveau record de ville.

Mon modèle de ville a les champs, name, state, country. L'État et le pays sont des codes postaux à deux lettres (j'utilise Carmen pour les valider). J'ai un attribut virtuel appelé full_name qui renvoie "City, State Code" (comme New York, NY) pour les villes nord-américaines, et "City, Country Name" (comme Paris, France) pour tous les autres.

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 

Ma question est, pour obtenir le texte de travail sur le terrain, comment puis-je créer une méthode de find_or_create qui peut accepter une chaîne avec le nom de la ville et soit code d'état ou le nom du pays et trouver ou créer ce disque?


Mise à jour

Inspirée par la réponse de Kandada je suis venu avec quelque chose d'un peu différent:

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 

Ce Rocking mes specs en ce moment, donc je pense que mon problème est résolu .

Répondre

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 

vous pouvez maintenant find_or_create_by_ *

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

Ce n'était pas * exactement * ce que je cherchais, mais vous m'a inspiré et je pense avoir trouvé une solution viable. Je vais l'ajouter à la question pour référence. – Andrew

Questions connexes