You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails技术问题:如何将一个Model的属性赋值给另一个Model

解决Rails中Model无法访问current_user及关联查询复用表单字段的问题

首先,咱们先明确错误的根源:current_user是Devise提供给控制器层面的方法,用于获取当前会话的登录用户,你的Goal模型实例是无法直接访问这个方法的——这就是你遇到NameError的核心原因。另外,我注意到你的User模型里有个关联小错误:has_one :goals应该改成has_one :goal(has_one关联对应的是单数模型名,这样关联关系才能正确建立)。

接下来,咱们用关联查询的思路来解决复用Waterusage字段的问题,分两步走:

1. 修正模型关联与调整属性复制方法

先把User模型里的关联改对,然后让Goal模型通过自身的用户关联来获取Waterusage数据,不再依赖外部的current_user:

# app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_one :waterusage, dependent: :destroy
  has_one :goal, dependent: :destroy # 这里改成单数:goal,匹配模型名
end

# app/models/goal.rb
class Goal < ApplicationRecord
  belongs_to :user

  # 从关联用户的waterusage中复制属性
  def copy_from_waterusage
    return unless user&.waterusage.present?
    
    # 复制所有相同字段,排除不需要的系统字段
    self.attributes = user.waterusage.attributes.except(
      'id', 'user_id', 'created_at', 'updated_at'
    )
    # 如果只需要复制特定字段,可以逐个指定:
    # self.household_size = user.waterusage.household_size
    # self.daily_water_target = user.waterusage.daily_water_target
  end
end

2. 在控制器中调用复制方法

在GoalsController的new动作里,利用当前用户的关联初始化Goal并触发属性复制:

# app/controllers/goals_controller.rb
class GoalsController < ApplicationController
  before_action :authenticate_user! # 确保用户已登录,Devise提供的方法

  def new
    @goal = current_user.build_goal # 通过关联构建Goal,自动绑定current_user
    @goal.copy_from_waterusage # 调用复制方法,复用Waterusage的字段值
  end

  def create
    @goal = current_user.build_goal(goal_params)
    if @goal.save
      redirect_to dashboard_path, notice: '目标创建成功!'
    else
      render :new
    end
  end

  private

  def goal_params
    # 允许需要的字段,根据你的表单实际字段调整
    params.require(:goal).permit(:household_size, :daily_water_target, :other_fields)
  end
end

为什么这样可行?

  • 当你用current_user.build_goal时,@goal已经自动关联了current_user,所以Goal模型里的user属性是有效的,能通过user.waterusage直接关联查询到用户已填写的用水数据。
  • 把属性复制逻辑放在模型里,但依赖的是模型自身的关联关系,而非外部控制器方法,这更符合Rails的MVC设计原则——模型负责数据逻辑,控制器处理会话与请求。

内容的提问来源于stack exchange,提问作者ezweizig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:21:55