Rails开发:如何将单个表单字段值同时存储到两个模型变量中
实现方案
第一步:移除表单中的冗余字段
首先找到app/views/books/_form.html.erb文件,删除可借阅藏书量对应的输入字段代码,一般是类似下面这段:
<div class="field"> <%= form.label :available_stock %> <%= form.number_field :available_stock %> </div>
注:如果你的可借阅藏书量字段名不是available_stock,替换为项目中实际定义的字段名即可
第二步:处理字段赋值(两种可选方案)
方案1:模型回调实现(更推荐,逻辑更聚合)
在app/models/book.rb中添加before_validation回调,新增记录时自动把总藏书量赋值给可借阅藏书量:
class Book < ApplicationRecord # 新增记录时自动同步可借阅库存 before_validation :sync_available_stock, on: :create private def sync_available_stock # 总藏书量字段如果是total_stock就用这个,替换为项目实际的字段名 self.available_stock ||= self.total_stock end end
这个方案的优势是无论你是通过表单提交、控制台创建、还是其他地方调用Book.create创建书籍,都会自动执行赋值逻辑,不需要重复写代码。
方案2:控制器参数处理
如果不想加回调,也可以直接在控制器的创建方法里处理参数,找到app/controllers/books_controller.rb的create方法,修改参数赋值逻辑:
def create # 先拿到其他参数,再手动赋值可借阅藏书量 @book = Book.new(book_params) @book.available_stock = @book.total_stock respond_to do |format| if @book.save # 原有逻辑不变 else # 原有逻辑不变 end end end
注意:如果用这个方案,需要确保可借阅藏书量没有被加入强参数的禁止列表,或者直接从强参数里移除该字段避免被非法覆盖
额外校验建议
可以在模型里加两个字段的校验,避免后续操作出现数据异常:
validates :total_stock, numericality: { greater_than_or_equal_to: 0 } validates :available_stock, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: :total_stock }
内容的提问来源于stack exchange,提问作者Jeffrey
相关产品推荐
相关产品推荐

