【发布时间】:2019-09-03 16:01:32
【问题描述】:
我有一个用于用户信息的嵌套模型的用户模型,并且我已经有一个带有country_select gem 的工作国家字段,但它不提供州和城市。
经过一番研究,我发现了这颗宝石ruby geocoder,正如它在文档中所说:
在任何基于机架的框架中 检测 HTTP 请求的位置 获取当前用户的城市和国家(使用 IP 地址)。一个 location 方法被添加到标准 Rack::Request 中,它返回一个 Geocoder::Result 对象:
# Rails controller or Sinatra app
city = request.location.city
country = request.location.country_code
基本上我想使用country_select gem 下车并使用ruby geocoder
我有两个模型:
models/user.rb
class User < ApplicationRecord
extend FriendlyId
friendly_id :username, use: :slugged
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_one_attached :avatar, :dependent => :destroy
# User Information
has_one :user_information, :dependent => :destroy
accepts_nested_attributes_for :user_information, :allow_destroy => true
def with_user_information
build_user_information if user_information.nil?
self
end
# Login with username or email
attr_accessor :login
validates :username, uniqueness: true, presence: true
def login
@login || self.username || self.email
end
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_h).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
elsif conditions.has_key?(:username) || conditions.has_key?(:email)
where(conditions.to_h).first
end
end
end
还有一个嵌套模型:
models/user_information.rb
class UserInformation < ApplicationRecord
belongs_to :user
has_one :gender, :dependent => :destroy
accepts_nested_attributes_for :gender, :allow_destroy => true
has_one :relationship, :dependent => :destroy
accepts_nested_attributes_for :relationship, :allow_destroy => true
def age
now = Time.current
dob = self.born_in
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
def country_name
country = ISO3166::Country[country_code]
country.translations[I18n.locale.to_s] || country.name
end
end
这是我的设计控制器
controllers/accounts_controller.rb
class AccountsController < Devise::RegistrationsController
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
resource_updated = update_resource(resource, account_update_params)
yield resource if block_given?
if resource_updated
set_flash_message_for_update(resource, prev_unconfirmed_email)
bypass_sign_in resource, scope: resource_name if sign_in_after_change_password?
session[:return_to] ||= request.referer
redirect_to session.delete(:return_to)
else
clean_up_passwords resource
set_minimum_password_length
session[:return_to] ||= request.referer
redirect_to session.delete(:return_to), alert: resource.errors.full_messages[0]
end
end
def settings
@user = current_user
if @user
render "devise/accounts/settings"
else
render file: 'public/404', status: 404, formats: [:html]
end
end
def passwords
@user = current_user
if @user
render "devise/accounts/passwords"
else
render file: 'public/404', status: 404, formats: [:html]
end
end
def security
@user = current_user
if @user
render "devise/accounts/security"
else
render file: 'public/404', status: 404, formats: [:html]
end
end
protected
def update_resource(resource, params)
if params[:current_password].blank? && params[:password].blank? && params[:password_confirmation].blank? && params[:email].blank?
resource.update_without_password(params.except(:current_password, :password, :password_confirmation, :email))
else
resource.update_with_password(params)
end
end
end
【问题讨论】:
标签: ruby-on-rails ruby rails-geocoder