【问题标题】:Method for converting strings into foreign key for a one-to-many association将字符串转换为一对多关联的外键的方法
【发布时间】:2018-04-19 16:38:27
【问题描述】:

我有一个 Rails 模型 Region 用于我访问过的地区。 RegionLocation 模型具有一对多关联,其中包含我在该区域内访问过的特定位置。

每个区域都有一个name 字符串列。我的路由设置为使用给定的Region.name 来形成大多数 URL - 例如/:name/new_location。这是出于审美原因,因为我不希望使用数字(region_id)来构成 URL。

因此,对于我添加到区域的每个新位置,都需要分配一个 region_idforeign_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 创建一个名为“Algonquin 省立公园”的新区域,我需要更新我的locations_controller - 将"algonquin provincial park" 连接到28,并将location.region_id 设置为28。这显然不是最优的。

有没有办法对我的newcreate 方法进行编程,以便自动为新的location 分配一个与它所属的regionregion_id 等效的foreign_key,而无需添加代码每次有新的region 时我的Location create 方法?

【问题讨论】:

    标签: ruby-on-rails model-associations


    【解决方案1】:

    作为介绍,您尝试执行的操作有时称为pretty urlsfriendly urls。您可以自己滚动,也可以使用宝石。看起来你已经走上了自己的道路(这也是我所做的)。如果您的 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
    

    【讨论】:

      猜你喜欢
      • 2012-06-10
      • 2016-07-21
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      相关资源
      最近更新 更多