如何在Rails SimpleForm中为Url添加祖父模型Category的表单字段
解决方法
方案1:在Url模型中处理虚拟属性的赋值逻辑
你当前仅定义了category_id的读取器和写入器,但写入器未实际更新关联的Domain对象。修改Url模型的category_id=方法,直接同步更新关联domain的category_id:
class Url < ApplicationRecord belongs_to :domain has_one :category, through: :domain def category_id category&.id end def category_id=(value) # 按需求自动初始化Domain(若尚未关联) self.domain ||= Domain.new domain.update(category_id: value) end end
同时需确保控制器的强参数允许category_id:
# urls_controller.rb private def url_params params.require(:url).permit(:你的其他属性, :category_id) end
方案2:在控制器中直接处理关联更新
若不想在模型层处理逻辑,可在控制器的create和update动作中手动更新domain的关联:
# urls_controller.rb def create @url = Url.new(url_params) if @url.save @url.domain.update(category_id: url_params[:category_id]) if url_params[:category_id].present? redirect_to @url, notice: 'Url创建成功' else render :new end end def update if @url.update(url_params) @url.domain.update(category_id: url_params[:category_id]) if url_params[:category_id].present? redirect_to @url, notice: 'Url更新成功' else render :edit end end private def url_params params.require(:url).permit(:你的其他属性, :category_id) end
额外提示
- 若Domain是通过Url的特定属性自动生成的(比如从Url提取域名创建Domain),需确保更新
category_id时Domain已存在或能被正确初始化。 - 如需保证Url和Domain的更新原子性(要么都成功,要么都回滚),可使用
ActiveRecord::Base.transaction包裹操作:
# 以控制器update动作为例 def update ActiveRecord::Base.transaction do @url.update!(url_params) @url.domain.update!(category_id: url_params[:category_id]) if url_params[:category_id].present? end redirect_to @url, notice: 'Url更新成功' rescue ActiveRecord::RecordInvalid render :edit end
内容的提问来源于stack exchange,提问作者Masa Sakano
相关产品推荐
相关产品推荐

