我是rails的新手并且正在尝试实现多态关联。基本上,我有一个设备对象,可以属于插座或端口,但不能同时属于两者。根据我的理解,多态关联将是这样做的方式,所以我这样建模:
class Device < ApplicationRecord
belongs_to :io, polymorphic: true
end
class Outlet < ApplicationRecord
has_one :device, as: :io
end
class Port < ApplicationRecord
has_one :device, as: :io
end
create_table "devices", force: :cascade do |t|
...
t.integer "io_id"
t.index ["io_id"], name: "index_devices_on_io_id"
end
现在,我在尝试将outlet
或port
分配给设备io
时遇到了一些麻烦:
无法写出未知属性
io_type
@outlet = Outlet.where(id: @outlet_id).first @device.io = @outlet if @device.save redirect_to @device
来自
class DevicesController < ApplicationController
def new
@device = Device.new(io_id: params[:io_id])
end
def create
@outlet_id = params[:device][:io_id]
@device = Device.new(device_params)
@outlet = Outlet.where(id: @outlet_id).first
@device.io = @outlet
if @device.save
redirect_to @device
else
render 'new'
end
end
现在,我很乐意接受一些关于为什么会抛出此错误的帮助,但这不是我的主要问题。调试时我有一个想法 - 如果我不在这里使用多态关联,这是否有意义?在我的device
表上创建两个单独的关联,一个指向port
表,另一个指向outlet
表并使它们都是可选的,这也没关系吗?一个将保持为null而另一个将被分配,然后我可以检查我的业务逻辑中的哪个字段!= null。我会在这条路上遇到问题吗?
答案 0 :(得分:1)
Device
需要io_id
和io_type
。否则,Device
将如何知道io_id
属于哪种类型的东西?
目前,如迁移所示,您只有io_id
。因此,您收到了io_type
的未知属性错误。
你应该将io_type
添加到你的桌子上,你应该好好去。
我建议您将create
操作修改为更像(有一些评论):
class DevicesController < ApplicationController
def new
@device = Device.new(io_id: params[:io_id])
end
def create
# how do you know the :io_id is for an Outlet and not a Port?
# if you add a hidden field that includes io_type, so that
# params[:device] = {io_id: x, io_type: 'Outlet'}, then you
# should be able to do something like:
@io = params[:device][:io_type].constantize.find_by(id: params[:device][:io_id])
# the has_one association provides the build_device method.
# if you use this method, then io_id and io_type will
# automatically be set on @device
@device = @io.build_device(device_params)
if @device.save
redirect_to @device
else
render 'new'
end
end