如何创建一个简单的嵌套注册表单?

时间:2015-04-28 18:18:29

标签: ruby-on-rails ruby ruby-on-rails-4 nested-forms nested-attributes

我真的被困住了。有人可以提供帮助吗?我究竟做错了什么?如何创建简单的嵌套表单?

我有两个模型,每个模型都有自己的资源:组织和成员。一个组织有多个成员,一个成员只是一个组织的成员。

如何创建一个注册新组织的简单嵌套表单以及该组织的一个成员?

我目前的尝试如下。新视图加载正常,但在提交表单时,我收到错误消息 unknown attribute 'org_name' for Member

虽然一种方法可能是表单对象和Activemodel,但在实现这样的第一种方式之前,我会在没有这样的情况下工作。

组织模式:

has_many :members, dependent: :destroy
accepts_nested_attributes_for :members, :reject_if => :all_blank, :allow_destroy => true

会员模特:

belongs_to :organization

组织控制员:

def new
  @organization = Organization.new
  @member = @organization.members.build
end

def create
  @organization = Organization.new(organizationnew_params)
  @member = @organization.members.build(organizationnew_params)
  if @organization.save && @member.save
    @member.send_activation_email     # Will Rails be able to get to this method? The method exists in multiple models and Rails should here use the version from the Member model.
    flash[:success] = "Please check your email to activate your account."
    redirect_to root_url
  else                          
    render 'new'
  end
end

def organizationnew_params
  params.require(:organization).permit(:org_name,
                                      :phone,
                   member_attributes: [:email,
                                      :username,
                                      :admin,
                                      :password,
                                      :password_confirmation
                                      ])
end

组织新视图:

<%= form_for(@organization) do |f| %>
  <%= f.text_field :org_name, %>
  <%= f.text_field :phone %>

  <%= f.fields_for :member do |p| %>
    <%= p.text_field :username %>
    <%= p.email_field :email %>
    <%= p.password_field :password %>
    <%= p.password_field :password_confirmation %>
    <%= hidden_field_tag :admin, true %> 
  <% end %>

  <%= f.submit "Sign up", class: "formbutton btn btn-default" %>
<% end %>

2 个答案:

答案 0 :(得分:2)

您应该学习表单对象的概念。您可以使用ActiveModel在Rails中轻松实现此功能。

class SignupForm
  include ActiveModel::Model

  # define your signup form attributes
  attr_accessor :organization_name, :organization_note, :user_name, :user_fullname, :user_email

  def save
    organization = Organization.create(
      organization_name: organization_name, note: organization_note
    )

    user = organisation.users.create(email: user_email, name: user_name,
      full_name: user_fullname)

    return true
  end
end

这不是完全正确的实现,但您可以从这里开始工作。您可以在表单中将此对象用作普通模型:

<%= form_for(@signup_form) do |f| %>
  <%= f.text_field :organization_name %>
  <%= f.text_field :user_name %>
  <%= f.text_Field :user_email %>
<% end %>

在控制器中:

class SignupsController
  def new
    @signup_form = SignupForm.new
  end

  def create
    @signup_form = SignupForm.new(params[:signup_form])

    if @signup_form.save
      # success
    else
      # display errors
    end
  end
end

当然,您还必须在SignupForm中实现一些验证,并在验证失败时处理案例。

答案 1 :(得分:0)

从“现状”获得“预期情况”的一种简洁方法是使用承诺。进行单个操作,链接(promisified)写操作。首先创建新组织。如果没有错误,请创建用户。将新用户作为管理员分配给新创建的组织也是如此。

https://github.com/lgierth/promise.rb

尽管如此,我会注意到,这只能部分地解决您的一个原始问题:新成员在加入现有组织时犯错误。承诺可以捕获用户尝试创建现有组织,并且您可以构建一些逻辑以将其添加为新成员...

对此的一个解决方案是为特定组织提供表单,新用户从该组织的链接访问表单,或者输入他们的组织并回到他们可能意味着的组织的紧密匹配(那里)是帮助做到这一点的API。)

我希望能给你一些想法。

如果您对一个大表单很好,只需组合视图即可。无论如何,您在最后一句中提到的新视图仍然需要,因此您至少要创建一个新视图。