我有一个针对我访问过的地区的轨道模型Region
。Region
与Location
模型具有一对多关联,该模型包含我在该区域访问过的特定位置。
每个区域都有一个name
字符串列。 我的路由设置为使用给定Region.name
来形成大多数 URL - 例如/:name/new_location
。这是出于美学原因,因为我不希望一个数字(region_id
)形成URL。
因此,对于我添加到区域的每个新位置,都需要分配一个region_id
foreign_key。 现在我正在通过在我的Location
中有一个region_name
专栏来做到这一点。 然后,我的new
位置表单有一个字段"区域名称",其中输入了一个字符串。
为了实际将新创建的location
与其region
相关联,我的locations_controller
中的create
方法包含一段代码,如下所示:
# CONVERT REGION_NAME TO REGION_ID
location = Location.new
l = location.region_name.downcase
if l == "chicagoland"
location.region_id = 3
elsif l == "roadtrip 2016"
location.region_id = 4
#...
end
location.save
redirect_to("/regions/#{region.name}/#{location.id}")
因此,对于我创建的每个新region
,我无法添加新位置,直到我手动将其字符串名称与其id
连接 - 通过向locations_controller
中的create
方法添加新代码。 因此,如果我使用id = 28
创建一个名为"阿冈昆省立公园"的新区域,我需要更新我的locations_controller
- 将"algonquin provincial park"
连接到28
,并将location.region_id
设置为28
。 这显然不是最佳的。
有没有办法对我的new
和create
方法进行编程,以便自动为新location
分配一个foreign_key,相当于它所属region
的region_id
,而无需每次有新region
时都向我的Location create
方法添加代码?
作为介绍,您尝试执行的操作有时是指漂亮的URL或友好的URL。您可以自己滚动,也可以使用宝石。看起来你已经走上了自己的道路(这也是我所做的)。如果您的name
字段包含非 url 好友元素,那么您可能需要考虑使用slugs
.我会留给你自己的研究。
在您的routes.rb
中,假设您有:
resources :regions, param: :name do
resources :locations
end
这将为您提供:
region_locations GET /regions/:region_name/locations(.:format) locations#index
POST /regions/:region_name/locations(.:format) locations#create
new_region_location GET /regions/:region_name/locations/new(.:format) locations#new
edit_region_location GET /regions/:region_name/locations/:id/edit(.:format) locations#edit
region_location GET /regions/:region_name/locations/:id(.:format) locations#show
PATCH /regions/:region_name/locations/:id(.:format) locations#update
PUT /regions/:region_name/locations/:id(.:format) locations#update
DELETE /regions/:region_name/locations/:id(.:format) locations#destroy
regions GET /regions(.:format) regions#index
POST /regions(.:format) regions#create
new_region GET /regions/new(.:format) regions#new
edit_region GET /regions/:name/edit(.:format) regions#edit
region GET /regions/:name(.:format) regions#show
PATCH /regions/:name(.:format) regions#update
PUT /regions/:name(.:format) regions#update
DELETE /regions/:name(.:format) regions#destroy
我们还假设您有:
class Region < ActiveRecord::Base
has_many :locations
end
和:
class Location < ActiveRecord::Base
belongs_to :region
end
然后,在locations_controller.rb
中,执行以下操作:
class LocationsController < ApplicationController
...
def create
@region = Region.find_by(name: params[:region_name])
@location = @region.locations.new(location_params)
if @location.save
redirect_to region_location_path(@region.name, @location)
else
# do something when the location doesn't save
end
end
...
private
def location_params
params.require(:location).permit(:some, :location, :attributes)
end
end