【问题标题】:Look for help on Ruby on Rails在 Ruby on Rails 上寻求帮助
【发布时间】:2012-10-25 16:31:26
【问题描述】:

我是 Ruby on Rails 的新手。我只是在现有数据库上构建 Web 应用程序。我使用 rails 为餐厅和位置表生成 2 个脚手架。之后我为这两个表设置了关系:

 class Restaurant < ActiveRecord::Base
  attr_accessible :created, :cuisine_fk, :dish_keywords, :dish_names, :factual_id, :first_name, :last_name, :name, :status


  has_many :locations 
end

class Location < ActiveRecord::Base
  attr_accessible :address1, :address2, :city, :created, :latitude, :longitude, :phone, :restaurant_fk, :state, :status, :url, :zip

  belongs_to :restaurant
 end

在为这些表设置此关系后,我没有使用“rake db:migrate”,因为我担心此操作会更改现有表。

当我运行这个命令行时

<%= restaurant.location.address1%> 

显示错误:

undefined method `location'

" NoMethodError in Restaurants#index

Showing C:/Sites/Dishclips/app/views/restaurants/index.html.erb where line #52 raised:

undefined method `location' for #<Restaurant:0x5853bb8> "

之后我尝试为文件设置外键:

class Location < ActiveRecord::Base
  attr_accessible :address1, :address2, :city, :created, :latitude, :longitude, :phone, :restaurant_fk, :state, :status, :url, :zip

  belongs_to :restaurant, :class_name => "Restaurant", :foreign_key => 'restaurant_fk'
 end

但它仍然不起作用。

在为表设置关系之后,有什么方法可以设置外键而不是使用“rails db:migrate”?非常感谢您的帮助。

【问题讨论】:

  • 您可以使用rake db:migrate 迁移数据库,而不是rails ...

标签: ruby ruby-on-rails-3 activerecord


【解决方案1】:

问题是你用错了位置。

由于餐厅有_many 个位置,您不能按照您提到的方式使用它。因为您有一个位置数组,实际上是一个 ActiveRecord 关系,所以为了访问关联的项目之一,您必须执行查询并获取其中一个元素。这是一个如何获取第一个元素的示例。

restaurant.locations.first.address1

如果餐厅只有一个位置,那么您应该将模型更改为

class Restaurant < ActiveRecord::Base
  attr_accessible :created, :cuisine_fk, :dish_keywords, :dish_names, :factual_id, :first_name, :last_name, :name, :status


  has_one :locations 
end

并按照您的方式访问该属性:

restaurant.location.address1

另外我假设你的数据库有你指定的列,否则你必须运行迁移。

问候!

【讨论】:

    【解决方案2】:

    Rails 关联被很好地覆盖here in the Rails Guides

    我将在这里引导您完成基本设置。

    $ rails generate model Restaurant name owner ...
    $ rails generate model Location restaurant_id:integer city ...
    

    然后您需要使用rake db:migrate 迁移您的数据库,以使数据库表更改生效。

    restaurant_id 允许我们在模型中设置关联,如下所示

    class Restaurant < ActiveRecord::Base
      has_many :locations, dependent: :destroy
      attr_accessible :name, :owner
    end
    
    class Location < ActiveRecord::Base
      belongs_to :restaurant
      attr_accessible :city  # no restaurant_id here
    end
    

    现在您可以按如下方式访问您的餐厅位置。

    r = Restaurant.create!(name: '...')
    l = Location.create!(city: '...')
    
    # Add association
    r.locations << l
    
    r.locations will now return an Array with l in it
    
    l.restaurant will return r
    

    尝试使用不同样式的关联,例如通过快速创建新的 Rails 应用程序并尝试某种关联,还有一些需要连接模型的关联。

    【讨论】:

    • 非常感谢,但我不敢使用“rake db:migrate”,因为我担心这会改变我现有表中的值。
    • Migrations 通常不会更改您的数据本身,而是更改您的数据库架构以适应您当前的需求。它可以查看$rails generate model ...$rails generate migration ... 生成的迁移,只需导航到您的db/migrations 文件夹并浏览最近的迁移。
    • 非常感谢,我会再次检查。
    【解决方案3】:

    现在我尝试这种方式,然后它可以工作。非常感谢。

    <td> 
          <% restaurant.locations.search(params[:restaurant_fk]).each do |location| %>
             <!--address =  <%= location.address1 %> + " " + <%= location.address2 %>-->
    
             <%= location.address1 %> 
             <%= location.address2 %> ,
             <%= location.city %> ,
             <%= location.state %> ,
             <%= location.zip %> 
    
          <% end %> 
    </td>
    

    【讨论】: