【问题标题】:Rails Foreign Key IssueRails 外键问题
【发布时间】:2011-04-13 21:44:09
【问题描述】:

对不起,如果这个问题看起来很简单,我对 Rails 非常陌生(几天前刚开始学习),但是在咨询了 Google 和“使用 Rails 进行敏捷 Web 开发”之后,我找不到答案。

Rails 2.3.8 在两个模型上创建外键时遇到问题。我的表格如下所示:

cars                                 manufacturer
----                                 ------------
car_make                             name
car_model                            country
car_class                            logo_url
image_url                            (and default 'id' created by Rails)
manufacturer_id
(and default 'id' created by Rails)

我的“car_make”和“name”字段基本相同;我创建的每辆汽车,我都希望能够将它与现有的制造商相关联。这是我试图在其上创建 FK 的列。

我的 car.rb 有 'belongs_to :manufacturer',我的 manufacturer.rb 有 'has_many :cars' 来建立一个制造商对多辆汽车的关系。但是,当我(通过脚手架)创建新车时,manufacturer_id 字段为空白。

我去了我的cars_controller,找到了正在使用的'create'方法,并尝试在下面添加第二行:

@car = Car.new(params[:car])
@car.manufacturer_id = car.manufacturer.id  # <===

这会产生“CarsController#create 中的 NameError”错误,我看到:

undefined local variable or method 'car' for #<CarsController:0x1034642f0>

Rails 似乎不喜欢我添加的行。我缺少什么来完成这项工作?

【问题讨论】:

    标签: ruby-on-rails join model foreign-keys


    【解决方案1】:

    嗯,您需要先找到制造商,然后才能将其安装到汽车上。

    @car = Car.new( params[:car] )
    m = Manufacturer.first # => as you can see you must already have one made
    @car.manufacturer = m
    @car.save
    

    car 未定义的原因是,好吧,您还没有定义它。您想将哪个汽车制造商分配给@car

    所以基本上你需要在制造汽车之前制造制造商。如果您填写的表格包含制造商的数据,请确保将其放在参数中的不同键下,例如params[:manufacturer],并执行与汽车类似的操作。也许像:

    @car = Car.new( params[:car] )
    @manufacturer = Manufacturer.find_or_create_by_name_and_country( params[:manufacturer][:name], params[:manufacturer][:country] )
    @car.manufacturer = @manufacturer
    @car.save
    

    【讨论】:

    • 嗯,有道理。我想找到与 car_make 字段对应的正确制造商 ID。例如,如果我的制造商表在名称列下填充了“Acura”、“Honda”和“Toyota”,并且我用 car_make 'Honda' 创建了一辆新车,我想找到正确的manufacturer_id “本田”行。
    • 啊哈,所以你不应该不要那样做。汽车品牌应该通过car.manufacturer.name找到,而不是在汽车本身上复制!
    • 为了破解它以使其正常工作(坏主意),您可以尝试:@car.manufacturer = Manufacturer.find_by_name(@car.car_make); @car.save,它将尝试通过您刚刚的汽车的 car_make 字段找到制造商更新了......再一次,如果你在这条路上走得太远,将会有一段糟糕的时光:)
    【解决方案2】:

    在您看来,您希望为制造商生成一个下拉列表(我会假设),因此您应该在表单中执行以下操作:

    <%= collection_select(:car, :manufacturer_id, Manufacturer.all, :id, :name) %>
    

    那么您的create 操作不需要显式设置manufacturer_id,因为它应该已经从表单接收到了。

    【讨论】:

    • 哇这个设计直观多了,不知道为什么我之前没有想到它:P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 2016-04-04
    相关资源
    最近更新 更多