2

Stackoverflow 的长期读者,但从未发现自己能够提出问题(尚未回答)。我想每件事都有第一次,所以就这样吧……

系统信息:
Ruby 版本 = 1.8.7
Rails 版本 = 3.2.2

情况:
我们有一个带有用户注册系统的应用程序。为了正确连接和填充我们所有的表格,我们在注册视图中使用复杂/嵌套表格。实际上,我的嵌套表单工作得很好,一切都按照它应该的方式填充,真的很棒。

这是问题所在:我需要在表单发布之后但在保存记录之前设置嵌套属性之一的值之一。

这是一个简单的示例,因此您可以更好地了解我在说什么:用户在我们的网站上注册。当他们注册时,会在用户数据表中创建一条记录。每个用户也被归类为一个 team_mate(加入表)并分配给他们自己的团队(起初)。但是,“团队”(表)中也有一个“别名”字段,在初始创建用户时,我们希望将其设置为用户的名字(无需让他们将名字输入到“表单上的别名字段)。

所以,我想问题是: 如何在表单发布之后和记录保存到数据库之前手动设置嵌套属性的值?

表模式的一个(简单)示例如下所示:

用户(id、first_name、last_name、created_at、updated_at)

Team_mates(id, user_id, team_id, created_at, updated_at) - 加入表

团队(id、别名、created_at、updated_at)

楷模:

用户.rb

class User < ActiveRecord::Base
  has_many :team_mates, :dependent => :destroy
  has_many :teams, :through => :team_mates, :foreign_key => :team_id
  accepts_nested_attributes_for :team_mates, :allow_destroy => true

  before_save :set_defaults

  private
    def set_defaults
      #want to set :users => :team_mates_attributes => :team_attributes => :alias to @user.first_name here

      # Would prefer to handle this here instead of in the controller.
    end
  end

团队.rb

class Team < ActiveRecord::Base
  has_many :team_mates, :dependent => :destroy
  has_many :users, :through => :team_mates, :foreign_key => :user_id

end

Team_mate.rb

class TeamMate < ActiveRecord::Base
  belongs_to :user
  belongs_to :team

  accepts_nested_attributes_for :team, :allow_destroy => true
end

控制器

用户控制器.rb

class UsersController < ApplicationController

def new
  @user = User.new
  @user.emails.build(:is_default_email => 1)
  @user.build_login

  @user.team_mates.build.build_team(:alias => 'Clinton444', :created_at => Time.new, :updated_at => Time.new)

  respond_to do |format|
    format.html
    format.json { render :json => @match }
  end
end

def create
  @user = User.new(params[:user])

  @user.attributes = ({ "user" => { "team_mates" => { "team" => { "alias" => @user.first_name } } } }) #--this doesn't work...

  @user.attributes = ({ :user => { :team_mates => { :team => { :alias => @user.first_name } } } }) #--neither does this...


  respond_to do |format|
    if @user.save
      format.html  { redirect_to(@user, :notice => 'User was successfully created.') }
      format.json  { render :json => @user, :status => :created, :location => @user }
    else
      format.html  { render :action => "new" }
      format.json  { render :json => @user.errors, :status => :unprocessable_entity }
    end
  end
end

看法

新的.html.haml

  = form_for(@user, :html => {:class => 'form-horizontal'}) do |f|
- if @user.errors.any?
  .alert
    %h2
      = pluralize(@user.errors.count, "error")
      prohibited this post from being saved:
    %ul
      - @user.errors.full_messages.each do |msg|
        %li
          = msg
%fieldset
.control-group
  = f.label :first_name, :class => "control-label"
  .controls
    =f.text_field :first_name, :class => "span8"

.control-group
  = f.label :last_name, :class => "control-label"
  .controls
    =f.text_field :last_name, :class => "span8"

= f.fields_for :emails do |e|
  =e.hidden_field :is_default_email, :class => "span8"

  .control-group
    = e.label :email, :class => "control-label"
    .controls
      =e.text_field :email, :class => "span8"

= f.fields_for :team_mates do |tm|
  = tm.fields_for :team do |t|
    =t.hidden_field :alias, :class => "span8"
    =t.hidden_field :created_at, :class => "span8"
    =t.hidden_field :updated_at, :class => "span8"

= f.fields_for :login do |e|
  .control-group
    = e.label :user_login, :class => "control-label"
    .controls
      =e.text_field :user_login, :class => "span8"

  .control-group
    = e.label :password_encrypted, :class => "control-label"
    .controls
      =e.text_field :password_encrypted, :class => "span8"

.control-group
  .controls
    =f.submit :class => 'btn btn-primary btn-medium'

最后

表单发布上的 Rails 服务器输出

  Parameters: {"user"=>{"team_mates_attributes"=>{"0"=>{"team_attributes"=>{"created_at"=>"Wed Jun 06 09:52:19 -0600 2012", "alias"=>"asfs444", "updated_at"=>"Wed Jun 06 09:52:19 -0600 2012"}}}, "first_name"=>"lkjlkjlsdfslkjeowir", "last_name"=>"ouisodifuoixv", "emails_attributes"=>{"0"=>{"is_default_email"=>"1", "email"=>"lpisfsopf@psflsjdk.com"}}, "login_attributes"=>{"user_login"=>"lkjsdfooiusfd", "password_encrypted"=>"[FILTERED]"}}, "utf8"=>"✓", "commit"=>"Create User", "authenticity_token"=>"CQLQ93/0VlncSzMlmtLPHgaVrrvjuHFN+lN6CYCsiR8="}

查看模型后,您可能想知道电子​​邮件/登录的来源。它们是在我们系统的模型中构建的,但实际上并不是这个问题的一部分,所以我省略了它们的代码。他们正在工作,所以问题不在那边。

4

1 回答 1

0

检查http://archives.ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

为了支持新对象的创建和现有对象的编辑,我们必须为一对多关联使用散列数组或为一对一关联使用单个散列。如果不存在 :id 属性,则假定它表示要创建的嵌套模型。

不是 100% 确定..我以前没有使用过\测试过,但这应该给你一个想法

@user.teams.each do |team| 
  team.team_mates do |team_mate|
    # To edit existing
    team_mate.team_attributes = [ { :id => team.id,  :alias => @user.first_name } ]

    # To create new
    team_mate.team_attributes = [ { :alias => @user.first_name } ]

    team_mate.save
  end 
end
于 2012-06-06T17:23:28.347 回答