我正试用RoR Active Records with Association。 并试图连接两个表,这是餐厅和restaurant_translations。这些是分开的,以支持多语言。
这是这两个表的定义。
create_table "restaurant_translations", id: false, force: :cascade do |t|
t.integer "id", limit: 4, default: 0, null: false
t.integer "restaurant_id", limit: 4
t.string "restaurantname", limit: 255
t.string "address", limit: 255
t.string "tel", limit: 255
t.text "description", limit: 65535
t.string "lang", limit: 255, default: "", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "restaurants", force: :cascade do |t|
t.string "restaurant_type", limit: 255
t.string "genre", limit: 255
t.string "url", limit: 255
t.string "fb", limit: 255
t.string "mailaddr", limit: 255
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
和模特。
class Restaurant < ActiveRecord::Base
has_many :restaurant_translations
end
class RestaurantTranslation < ActiveRecord::Base
self.table_name = 'restaurant_translations'
belongs_to :restaurant
end
然后是控制器造成我的头痛。
class RestaurantController < ApplicationController
def list
@restaurants = Restaurant.includes(:restaurant_translations).where('restaurant_translations.lang = ?', "en").references(:restaurant_translations)
logger.debug @restaurants
end
end
查看文件(.slim)是这样的。
h1 = t :restraunt_list_title
table
thead
tr
th = t :restraunt_list_type
th = t :restraunt_list_name
th = t :restraunt_list_url
th = t :restraunt_list_genre
th = t :restraunt_list_addr
tbody
- @restaurants.each do |restaurant|
tr
td = restaurant.restaurant_type
td = restaurant.restaurant_translations.first.restaurantname
td = link_to 'here', restaurant.url
td = restaurant.genre
td = restaurant.restaurant_translations.first.address
br
因此,发生错误&#39;没有方法错误&#39;。告诉我如何表达关联表参数。提前谢谢。
答案 0 :(得分:1)
我猜你正试图调用restaurant_translations
上定义的名字方法,在这种情况下你应该打电话:
tr
td = restaurant.restaurant_type
td = restaurant.restaurant_translations.first.name
td = link_to 'here', restaurant.url
td = restaurant.genre
td = restaurant.restaurant_translations.first.address
然而,对您的代码进行一些更正,
您不需要餐厅的restaurant_id
列,因为已将其定义为id
,除非您还要将restaurant
绑定到restaurant_translation
1}}通过belongs_to关联,在这种情况下,您需要restaurant_translation_id
列。
我发现你排除了id
中的restaurant_translation
列并再次添加它,这似乎有点多余,而且如果你想利用一些先进的ActiveRecord功能,您需要id
列
您不需要在restaurant_translation
模型上指定table_name,因为Rails推断
在restaurants_controller
中,您正在分配@restaurants
并立即将其重新分配给restaurant_translations
。我不知道你打算做什么,但我认为没错。
尝试在应用程序中保持一致的名称,以便将来的自己能够理解它。一个例子是使用restraunt_list_type
,我想你想说restaurant_list_type
可能还有其他人,但这些是我眼睛立即抓住的。
<强>更新强>
您应该检查数据库,确保所有restaurants
至少有一个restaurant_translation
。错误:...for NilClass
表示您的restaurant_translation
是一个空数组。如果您想要获取至少有restaurants
的所有restaurant_translation
,那么您应该在控制器中使用joins vs includes
,这样:
Restaurant.joins(:restaurant_translations).where(restaurant_translations: { lang: "en"}).references(:restaurant_translations)
但是,如果您要获取所有餐厅,包括/不包含restaurant_translations
,那么我说您应该使用Object#try
来回答您之前对问题的回答。方法:
tbody
- @restaurants.each do |restaurant|
tr
td = restaurant.restaurant_type
td = restaurant.restaurant_translations.first.try(:restaurantname)
td = link_to 'here', restaurant.url
td = restaurant.genre
td = restaurant.restaurant_translations.first.try(:address)