Rails模型设计决策

所以为了简化我的工作,我的应用程序中有3个主要模型; 城市,餐厅和食谱。 一个城市有许多餐馆,餐厅有很多食谱。 每个城市都有一个列出该城市餐馆的页面,同样每个餐馆页面都有其页面中列出的食谱。 在我的城市页面中还有一个“添加新餐厅”按钮,当用户点击此按钮时,用户将被带到新的餐馆页面,其中包含以下链接:

 

但是这个页面是一个通用页面,用户可以将餐厅添加到任何城市,我如何修改我的设计,以便新的餐厅表单只会添加一个新的餐厅到那个城市。

编辑:谢谢你的回答。 所以现在这是我的餐厅创建方法..因为new_restaurant_path是一个表单,它有其他参数而不仅仅是一个城市。 所以我明白我可以通过@city = City.find(params [:city])找出我餐厅的城市,但是如何将此添加到此行的其余参数中@restaurant = Restaurant.new( PARAMS [:餐厅])

 def create @restaurant = Restaurant.new(params[:restaurant]) end 

有路线

您可以创建这样的路线:

 /cities/:city_id/restaurants/new 

有:

 resources :city do resources :restaurants end 

和助手:

 <%= link_to 'Add New Restaurant', new_city_restaurant_path(city) %> 

帮助中的params

或者,您可以在当前路径助手中传递参数并在控制器中处理它:

 <%= link_to 'Add New Restaurant', new_restaurant_path(city_id: city.id) %> 

这将使用此URL:

 /restaurants/new?city_id=123 

对于这两种方法,控制器

并在控制器中:

 def create city = City.find(params[:city_id]) @restaurant = city.restaurants.build params[:restaurant] if @restaurant.save ... end 

2种方法来实现这一目标

1)为您的城市路径添加嵌套路径以供餐馆使用new_city_restaurants_path(@city.id)您必须在cities文件夹中创建文件夹和视图,或者将所有餐馆文件夹移动到cities文件夹中。 还有一些其他位和馅饼需要整理,如控制器和助手,这可能不适合。

所以可能更简单

2)将城市ID添加到link_to作为参数,并更改餐厅控制器中的新操作以检查是否存在城市ID并采取适当的操作,以便最终得到类似这样的内容

 <%= link_to 'Add New Restaurant', new_restaurant_path(:city => @city.id) %> 

然后在控制器的新操作中添加检查

  def new if params[:city] #find the city and build a new restaurant object city = City.find(params[:city_id]) @restaurant = city.restaurants.build params[:restaurant] else # just create a new restaurant object as normal @restaurant = Restaurant.new end # ...Rest of action end 

编辑以回应评论

因为您已针对城市对象构建了餐馆,所以城市ID将被分配给餐馆对象,处理此问题的方式取决于new.html.erb模板中的代码。

如果您有城市选择框,则使用@restaurant对象中的城市ID预先选择城市。 这样就不需要更改params哈希或控制器创建操作中的任何代码。 因为我没有你的new.html.erb代码,所以很难进一步建议你接受的答案以错误的方式处理IMO。

您也可以从Ryan Bates的嵌套资源video中受益http://railscasts.com/episodes/139-nested-resources