【问题标题】:Rails how to get associated model attributesRails 如何获取关联的模型属性
【发布时间】:2012-11-21 00:33:00
【问题描述】:

我有下面的方法将数据保存到 users 表以及 user_details 表。

当我将 @newUser 变量传递给 EmailMailer 时,我无法访问 user_details 属性。如何在 @newUser 对象中传递 user_details 而无需重新查询数据库?

型号

class User < ActiveRecord::Base
  has_one :user_details, :dependent => :destroy
  accepts_nested_attributes_for :user_details
  attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :login, :home_phone, :cell_phone, :work_phone, :birthday, :home_address, :work_address, :position, :company, :user_details_attributes
end

class UserDetails < ActiveRecord::Base
  belongs_to :user
  attr_accessible :first_name, :last_name, :home_phone, :cell_phone, :work_phone, :birthday, :home_address, :work_address, :position, :company
end

控制器

# POST /users
def create
        @newUser = User.new(params[:user], :include =>:user_details)

        # create password
        require 'securerandom'
    password = SecureRandom.urlsafe_base64(8)

        @newUser.password = password

        respond_to do |format|
            if @newUser.save

                @newUser.build_user_details
                # Tell the UserMailer to send a welcome Email after save
                EmailMailer.welcome_email(@newUser).deliver
                # To be used in dev only. Just tests if the email was queued for sending.
                #assert ActionMailer::Base.deliveries.empty?
                format.html {
                    flash[:success] = "User created successfully"
                    redirect_to(contacts_path)
                }
            else 
                format.html {
                    flash[:error] = flash[:error].to_a.concat resource.errors.full_messages
                    redirect_to(contacts_path)
                }
            end
        end
  end

【问题讨论】:

  • @newuser 是一个实例变量,您可以将邮件程序视为视图,并在其中使用实例变量,就像在视图中一样。
  • 我认识 ryan,但我不确定如何让 @newUser 实例变量可以访问 user_details。
  • @Catfish 仅供参考,您不应该像这样内联发送电子邮件。他们应该被转移到后台处理。您可以使用 DelayedJob 或 Resque 轻松完成此操作。像这样的内联电子邮件递送会对您的表现产生严重影响。

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

这样的事情可能会满足你的需求。

class User < ActiveRecord::Base
  has_one :user_details
  accepts_nested_attributes_for :user_details
  after_initialize :build_user_details
  ...
end

# In controller
def create
  @new_user = User.new
  @new_user.attributes = params[:user]
  if @new_user.save
    # do mail thing
  else
    # other thing
  end
end

【讨论】:

  • 如果我尝试这种方式,我会收到错误undefined method after_initialization
  • 对不起。它是after_initialze 而不是after_initialization。已更新。
  • 这似乎解决了当前的问题,但现在我遇到了另一个奇怪的问题。我会问另一个问题。
  • 好的,真正的解决方案是删除“after_initialize”代码,并按照您的建议使用@new_user = User.new @new_user.attributes = params[:user]
【解决方案2】:

您需要在保存 @newUser 之前建立 UserDetails 关联

@newUser.build_user_details
if @newUser.save
  #send mailer
else
  #do something else
end

您也可以在保存@newuser 后使用创建操作

if @newUser.save
   @newUser.create_user_details
   #send mailer
else
   #do something else
end

顺便说一下,R​​uby/Rails 约定是使用snake_case 作为变量。所以@newUser 应该是@new_user。

【讨论】:

  • 我很确定我尝试了您的第一个解决方案,但它没有将我的 user_details 保存到数据库中。我将尝试您的第二个解决方案,因为我不知道 create_user_detailscreate_user_detailsbuild_user_details 方法来自哪里?
  • 这些方法是method_missinghas_one 关系提供给您的助手。第二种解决方案不会为您节省查询,因为它会导致两次写入。第一个解决方案应该可以正常工作。或者,您可以将生命周期方法附加到用户,该方法在 user 初始化之后初始化 user_detail 对象。
  • 使用您的第一个解决方案,如果我将@newUser.build_user_details 放在@newUser.save 之后,您可以看到此链接中的 user_details 正在被删除 - pastebin.com/fZ7zGimD。这是为什么?如果我完全删除 build_user_details 行 user_details 得到保存。
  • 第二种解决方案似乎在做同样的事情
  • 您将哪些值作为参数传递给 user_details 表?您是否有可能阻止它保存的验证?
猜你喜欢
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2013-07-24
  • 2018-10-23
相关资源
最近更新 更多