关联ActiveRecords表时不显示方法错误

时间:2016-06-11 23:08:24

标签: ruby-on-rails ruby activerecord

我正试用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;。告诉我如何表达关联表参数。提前谢谢。

enter image description here

PS。修复后面的视图后,结果是这样的。 enter image description here

比照restaurant_translation就是这样的。 enter image description here

1 个答案:

答案 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

然而,对您的代码进行一些更正,

  1. 您不需要餐厅的restaurant_id列,因为已将其定义为id,除非您还要将restaurant绑定到restaurant_translation 1}}通过belongs_to关联,在这种情况下,您需要restaurant_translation_id列。

  2. 我发现你排除了id中的restaurant_translation列并再次添加它,这似乎有点多余,而且如果你想利用一些先进的ActiveRecord功能,您需要id

  3. 您不需要在restaurant_translation模型上指定table_name,因为Rails推断

  4. restaurants_controller中,您正在分配@restaurants并立即将其重新分配给restaurant_translations。我不知道你打算做什么,但我认为没错。

  5. 尝试在应用程序中保持一致的名称,以便将来的自己能够理解它。一个例子是使用restraunt_list_type,我想你想说restaurant_list_type

  6. 可能还有其他人,但这些是我眼睛立即抓住的。

    <强>更新 您应该检查数据库,确保所有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)