Please bear with me, as I'm new to programming in Rails and in general. I have a very limited understanding of how the models, views, controllers function but I've been learning as fast as I can.
I am having trouble with how I can generate semi-static intermediate pages based off the data I already have. Right now it's just a zip code search, a page with a list of results and a shop page. I want it structured by State-city-list-shop
In my database are shop locations that have been geocoded and made accessible on the client side via zip code search. So I'm dealing with a Shops controller that has the usual scaffold type setup so a url looks like /shops/1 for the show view. What I would like is shops/alaska/anchorage/the-name-of-the-shop with breadcrumbs.
I don't have a "States" or "Cities" controller which is how I would assume you'd have to do it in order to get the routes built.
I made static State template pages, and for each State I list the cities with the links looking like City. I have an index.html file in each of the State folders but there's nothing in /shop/state/city
I did it like that because I can get results from this:
/shops/find_shops?=zip=City&Distance=5
Which if I could get the same result for /state/city/shops I'd be happy.Because then I could click one of the shops in that list and it would take me to the shops page which is /shops/7499 (:id) and it would be better to have /state/city/shop-name
Here's the Shop controller - the admin is simply protecting the public from editing the shop address info. As you'll see it's taking a csv file, parsing and saving to the database.
def admin_index
#@shops = Shop.find(:all)
@shops = Shop.paginate( :per_page => 35,
:page => params[:page])
@shops_to_geocode = Shop.fetch_not_geocoded
end
def geocode_shops
@shops_to_geocode = Shop.fetch_not_geocoded
cnt = 0
for shop in @shops_to_geocode
shop.geocode_raw_address
shop.save!
end
redirect_to :action => 'admin_index'
end
def upload_file
file_path = params[:file_path]
if file_path
Shop.import( file_path )
end
redirect_to :action => 'admin_index'
end
# GET /shops
# GET /shops.xml
def index
@zip = params[:zip]
@distance = params[:distance]
if @zip && @distance
@shops = Shop.find(:all, :origin => @zip, :conditions => ["distance < ?", @distance])
logger.debug( "found #{@shops.length} shops" )
if @shops.length == 0
geo = GeoKit::Geocoders::MultiGeocoder.geocode( @zip )
errors.add(:address, "Could not Geocode address") if !geo.success
@centerLat, @centerLng = geo.lat,geo.lng if geo.success
else
@centerLat = @shops[0].lat
@centerLng = @shops[0].lng
end
else
@shops = []
geo = GeoKit::Geocoders::IpGeocoder.geocode(request.remote_ip)
if geo.success
@centerLat, @centerLng = geo.lat,geo.lng
else
logger.debug( "unable to geocode remote ip" )
@centerLat = 42
@centerLng = -120
end
end
if @distance.nil?
@distance = 5
end
And Here's the Shop.rb
require 'net/http'
class Shop < ActiveRecord::Base
acts_as_mappable
DATA_FILE_COLS =
[
"---",
"Site",
"Zip Search",
"Shop",
"Address",
"Phone",
"Make",
"Affiliations",
"Specialties",
"Amenities",
"Timestap",
]
FIELDS =
{
"---" => "-1",
"Site" => "-1",
"Zip Search" => "-1",
"Shop" => "name",
"Address" => "raw_address",
"Phone" => "phone_number",
"Make" => "make",
"Affiliations" => "affiliations",
"Specialties" => "specialties",
"Amenities" =开发者_StackOverflow> "amenities",
"Timestap" => "-1"
}
def full_address
"#{address_1} #{city} #{state} #{postal_code}"
end
def valid_for_geocoding?
rtn = true
if self.full_address.nil? || self.full_address.to_s.empty?
rtn = false
end
return rtn
end
def geocode_address
geo = GeoKit::Geocoders::MultiGeocoder.geocode( full_address )
errors.add(:address, "Could not Geocode address") if !geo.success
self.lat, self.lng = geo.lat,geo.lng if geo.success
end
def geocode_raw_address
geo = GeoKit::Geocoders::MultiGeocoder.geocode(self.raw_address)
if ( geo.success )
self.address_1 = geo.street_address
self.city = geo.city
self.state = geo.state
self.postal_code = geo.zip
self.lat = geo.lat
self.lng = geo.lng
end
end
def self.import( file_path )
url = 'http://example.com'
#file = '/filename.txt'
file = file_path
response = Net::HTTP.get_response(URI.parse(url + file))
body = response.body
lines = body.split("\r\n")
line_cnt = 0
lines.each { |line|
if line_cnt > 1
words = line.split("\"")
cnt = 0
shop_atrbs = Hash.new
words.each { |word|
if word != ","
#puts "#{fields[cnt]} : #{word.strip}"
field = FIELDS[DATA_FILE_COLS[cnt]]
if field != "-1"
shop_atrbs[field] = word.strip
end
cnt = cnt + 1
end
}
shop = Shop.new
shop.update_attributes(shop_atrbs)
geo = GeoKit::Geocoders::MultiGeocoder.geocode(shop.raw_address)
shop.address_1 = geo.street_address
shop.city = geo.city
shop.state = geo.state
shop.postal_code = geo.zip
shop.lat = geo.lat
shop.lng = geo.lng
shop.save
end
line_cnt = line_cnt + 1
} #f.each{ |line| puts '#{f.lineno}: #{line}' }
end
def self.fetch_not_geocoded
find( :all,
:conditions => ['lat IS NULL || lng IS NULL || lat = ? || lng = ?', "", ""],
:limit => 10000)
end
def self.find_for_sitemap(offset, limit)
find( :all,
:select => 'id, name, updated_at',
:order => 'updated_at DESC',
:offset => offset,
:limit => limit )
end
end
So, what I want to have work is - /Alaska/Anchorage/Shops-List/ (clean URL)
What I can do right now is - /find_shops?zip=anchorage&distance=5
Lastly, this is rails 2.3.2 and I've spent so much time trying to get it converted to rails 3.0 but haven't had success with that yet.
Have you read the Rails Routing guide "Rails Routing from the Outside In"? In particular section 4 covers how you might achieve this.
精彩评论