需要帮助 rails 使用模型属性进行路由

Need help rails routing using model attribute

我目前正在学习 rails 并且正在构建我的第一个 rails 项目。我创建了一个 :restaurant 模型(以及其他模型 - 预订和用户),其中包含几个属性,包括 :city。这是我的架构:

create_table "restaurants", force: :cascade do |t|
    t.string "name"
    t.string "city"
    t.string "website"
    t.string "phone_number"
    t.integer "ratings"
    t.integer "capacity"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

在我的根“/”页面中,我将唯一的城市值显示为带有 link 的列表。我希望用户可以通过点击他们所在的城市或计划访问的城市来浏览餐馆(最好使用 link '/restaurants/#{city}' 并最终进入一个页面该城市的餐馆列表。

我一直在想办法,目前我的相关路线是这样的:

resources :restaurants do 
    resources :bookings
  end

我尝试将 :city 创建为嵌套资源,但结果是 url '/restaurants/:restaurant_id/:city' 这不是我想要实现的目标。

但最重要的是,我无法弄清楚用户在根页面中单击的 'city' 是如何导致包含该城市所有餐馆的页面的。

任何建议都会很有帮助。

谢谢。

路线非常灵活,给你很大的力量。

第一个选项:我建议更传统的Rails方法:将您的城市分离成自己的模型并将它们与餐厅相关联。

像这样:

class City < ApplicationRecord
  has_many :restaurants, inverse_of: :city
  ...
end

class Restaurant < ApplicationRecord
  belongs_to: city, inverse_of: :restaurants
  ...
end

然后,我会稍微移动一下您的数据库:

create_table :cities do |t|
  t.string :name, null: false
  t.timestamps
end

create_table :restaurants do |t|
  t.string :name
  t.references :city
  t.string :website
  t.string :phone_number
  t.integer :rating
  t.integer :capacity
end

这将使您走上嵌套路由的正确轨道,例如:

/cities/:city_id/restaurants

第二个选项是在RESTful路径上徘徊,玩转路线的灵活性:

(我建议远离 /restaurants/:city 而只使用 /:city,但想法是一样的)

# routes.rb
# warning! Put this towards the very end of your file. Even then, any URL you try to hit that fits
# this pattern will get sent to this controller action. e.g. "yoursite.com/badgers"
# you'll need to explore handling RecordNotFound and redirecting someplace else 
get '/:city', to: 'restaraunts#by_city', as: 'restaurants_by_city'

现在在您的餐厅控制器中:

class RestaurantsController < ApplicationController
  ...
  def by_city
    city = params[:city] # this will be whatever is in the url

    @restaurants = Restaurant.where(city: city)

    # you'll need some error handling:
    redirect to root_path if @restaurants.empty?
    ...
  end
end