提问人:pebwindkraft 提问时间:12/19/2022 更新时间:12/20/2022 访问量:58
RubyOnRails 使用第二个表中的数据进行form.collection_select
RubyOnRails form.collection_select with data from second table
问:
我正在尝试在订单中使用form.collection_select,其中包含来自名为 products 的第二个模型的数据。我想在我的 HTML 页面中使用 products 表中的字段“product_reference”作为选择器。 在订单表单中,我想将所有product_references呈现在选择器中,让用户做出选择,product_reference,并将相应的product_id存储在订单表单(和数据库表字段)中。 我有两个表,通过id连接,如以下模式所示:
create_table "orders", force: :cascade do |t|
t.datetime "order_date"
t.bigint "product_id", null: false
...
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["product_id"], name: "index_orders_on_product_id"
end
create_table "products", force: :cascade do |t|
t.string "brand"
t.string "product_reference"
t.string "description"
...
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["product_reference"], name: "index_products_on_product_reference", unique: true
end
使用以下描述的关系:
app/models/order.rb
class Order < ApplicationRecord
belongs_to :product
end
app/models/ product.rb
class Product < ApplicationRecord
has_many :orders
end
我使用了 rails 控制台,并以这种方式得到了我想要的东西:
Product.all.map(&:product_reference)
Product Load (0.8ms) SELECT "products".* FROM "products"
=>
["C-Beau33",
"C-Beau50",
...
"B-Volk33",
"B-Volk66"]
在我的控制器中,我尝试将这个 dezired 结果分配给@prodrefs,然后我可以在collection_select中使用它: 订单控制员:
# GET /orders/new
def new
@order = Order.new
@prodrefs = Product.all.map(&:product_reference)
end
我在我的html视图中使用了它: app/views/orders/_form.html.erb
<%= form.collection_select :order_id, Product.all, :id, @prodrefs, :prompt => 'Select Ref' %>
并点击此错误消息:
["C-Beau33", "C-Beau50", ... "B-Volk33", "B-Volk66"] is not a symbol nor a string
我认为此错误消息与我的问题没有完全相关,当尝试仅添加“.to_s”时,我只会收到另一个错误
undefined method `#<Product::ActiveRecord_Relation:0x00007fa1087ddda8>' for #<Product id: 1, brand: "Beaufort", product_reference: "C-Beau33",...>
到目前为止已经做了什么:
在直接在这个“product_reference”上使用外键的旧方法中,我能够在我的观点中使用此代码,就像一个魅力一样工作,用户可以从浏览器的下拉菜单中选择product_reference:
<%= form.collection_select :fk_prodref, Product.order(:product_reference), :product_reference, :product_reference, :prompt => 'Select Ref' %>
此fk_approach现在已被拒绝,因为需要进行一些扩展,并具有新的模型关联。
查看 RubyOnRails 指南,我可以找到关于城市的例子,以及 ActionView::Helpers::FormBuilder 页面中的解释,我看到的描述是:
collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
所以我相信我text_method是这里的问题所在。当我从指南中翻译时,我得出了这个逻辑:
collection_slct html in city example
method -> <option value=>
collection -> Berlin
value_method -> <select ... id="city_id">
text_method -> <select name="city_id">
这让我相信,我希望将第二行(集合)作为我所有的产品参考。但是我错过了text_method上的要点,因为错误消息将我引导到那里。任何帮助都非常感谢
答:
你很接近。有点像几种可行的方法的大杂烩,但你已经很接近了。
如果您愿意,您可以在控制器中执行此操作,尽管它只是
@products = Product.all.order(:id). # or whatever order you would like
然后在您的表格中
<%= form.collection_select( :product_id, @products, :id, :product_reference, prompt: 'Select Ref') %>
- 第一个参数是您要保存的属性,在您的例子中, 在上面有order_id的地方,真的很product_id。
- section 参数是集合的对象列表
- 第三个参数是集合中需要保存到 product_id 属性的属性。在这种情况下,它是
id
- 第四个参数是要在下拉列表中显示的属性名称,
:product_reference
- 最后,第五个选项是提示
评论