我想創建一個表單,其中可以輸入:外部模型實例的名稱,該實例應該轉換爲:要存儲爲該對象的id對象的名稱外鍵。在窗體中輸入名稱,但將ID保存爲外鍵
我發現了這樣做的不同方式,但它們都有很大的缺點。 例如:我有兩個型號A和B:
class A < ActiveRecord::Base
belongs_to :b
validates :b_id, presence: true, inclusion: {in: B.all.map(&:id)}
end
class B < ActiveRecord::Base
end
的_form.html.erb使用該字段,其中一個可以輸入字符串:
<%= form_for(@a) do |f| %>
...
<div class="field">
<%= f.label :b %><br>
<%= f.text_field :b %>
</div>
...
<% end %>
而對於控制器看起來像這樣:
class AController < ApplicationController
...
before_action :get_a_id, only: [:create, :update]
...
private
def page_params
params.require(:a).permit(:name, :b_id, :content)
end
def get_a_id
b_name = params[:a][:b]
b = B.find_by(name: b_name)
b_id = b.id unless b.nil?
params[:a][:b_id] = b_id
end
end
如果在數據庫中找到輸入的:名稱在文本字段中,則此方法有效。如果未找到,則顯示驗證錯誤,但text_field未被高亮顯示,並且爲空(而不是包含先前輸入的字符串)。 我認爲這是因爲該字段應該包含B的對象而不是名稱,並且這在字符串錯誤的情況下不存在。 我認爲,這樣操縱它並不是一個好主意。
有沒有一種很好的方法來實現這一目標?我不想在這裏下拉,因爲稍後可能會有很多值。當然下一步將是實施某種自動完成,但這不應該算在這裏。
從理論上講,應該有一種方法將text_field與新的B對象關聯,但只顯示:name。然後控制器可以嘗試找到具有該名稱的數據庫對象,並用它替換佔位符。如果找不到正確的對象,則驗證失敗,但該值仍顯示(當然,驗證需要隨後進行更改)。
任何方式來實現這樣的事情在一個不錯的方式是讚賞。只要讓我知道,如果有什麼不清楚。
編輯:
什麼其實我是想實現:
表單字段,允許輸入一個字符串。應該將該字符串傳遞給控制器,在該控制器中執行搜索,將該字符串轉換爲對象(B)的id,以便將其用作外鍵。當類A的對象被保存時,驗證器應該檢查該ID是否被設置並存在。如果驗證失敗,則應該突出顯示字段(帶有字符串),並顯示錯誤消息。
主要的問題是,具有名稱的字符串不在模型中。只是身份證是。所以如果id被驗證(什麼是正確的方法),那麼錯誤消息就不會被作爲字符串關聯到包含該名稱的字段。
您可以使用jquery [autocomplete](https://jqueryui.com/autocomplete/)來建議對象b的名稱,並且用戶可以從結果中選擇 – Dawcars
謝謝@Dawcars,但這只是下一步它漂亮向上。主要問題是如何在輸入名稱的同時存儲該對象的ID並維護一個仍然與表單關聯的良好模型驗證。 – Klumbe