Cocoon Gem:编辑视图仅显示空表单字段

时间:2017-11-28 14:08:31

标签: ruby-on-rails many-to-many cocoon-gem

我在我的Rails应用程序中使用cocoon将员工(用户)分配给项目(多对多连接)。关联的创建工作正常,但每次添加另一个员工时,cocoon会在编辑视图中添加一个空的表单字段。编辑视图中的其他任何cocoon表单字段都不会填充。这可能是由于使用下拉列表(选择)?

当我在浏览器中检查表单时,我可以看到每个字段似乎都被分配给其中一个关联,但选择仍然是空的。 Screenshot of my View

我想要实现的是,每个关联都显示在一个cocoon表单字段中,以便可以编辑它们。感谢您提前提供任何帮助!

我的代码在下面(对不起任何一塌糊涂,这是我第一次尝试两种型号的多对多连接)。

项目修改视图

 <%= form_for(@project, :url => project_path, method: :patch) do |f| %>

    <div class="form-group">
        <%= f.label :title %>
        <%= f.text_field :title, class: "form-control" %>
    </div>

    <div class="form-group">
        <%= f.label :customer %>
        <%= f.text_field :customer, class: "form-control" %>
    </div>

    <%= f.fields_for :user_projects do |collab| %>
        <% collab.hidden_field :project_id, value: @project.id %>
        <%= render 'user_project_fields', f: collab %>
    <% end %>
    <div class="add-collaborator">
        <%= link_to_add_association "add", f, :user_projects, class: "btn btn-mmc" %>
    </div>

    <div class="actions">
        <%= f.submit "Save Changes", class: "btn btn-mmc btn-mmc-medium" %>
    </div>
<% end %>

cocoon field partial

<div class="nested-fields">
    <%= f.label "Select User" %>
    <div class="form-group custom-form-group">
        <%= f.select(:user_id, options_for_select(User.all.map { |u| [u.email, u.id] }), {include_blank: true}, {class: 'form-control'})%>
        <div class="btn-user-project">
            <%= link_to_remove_association "x", f, class: "btn btn-mmc-attention btn-mmc" %>
        </div>
    </div>
</div>

项目模型

class Project < ApplicationRecord
    has_many :user_projects
    has_many :users, :through => :user_projects

    accepts_nested_attributes_for :user_projects, reject_if: :all_blank, allow_destroy: true
end

用户模型

class User < ApplicationRecord
    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

    has_many :user_projects
    has_many :projects, :through => :user_projects
end

项目控制器

def edit
    @project = Project.find(params[:id])
    @project.user_projects.build
end

def update
    @project = Project.find(params[:id])
    @project.update(project_params)
    @new_collaborator = UserProject.new(user_id: params[:user_id], project_id: params[:project_id])
    @new_collaborator.save
    if @project.update(project_params) && @new_collaborator.save
        redirect_to projects_path
    else
        render :edit
    end
end

private

def project_params
    params.require(:project).permit(:title, :customer, :delted, user_projects_attributes: [:user_id, :project_id]).reject { |_, v| v.blank? }
end

2 个答案:

答案 0 :(得分:0)

那是因为你要两次创建对象。

第一次:

@project.update(project_params) # from accepts_nested_attributes_for

第二次:

@new_collaborator = UserProject.new(user_id: params[:user_id], project_id: params[:project_id])
@new_collaborator.save

P.S。

你能展示project_params方法吗?我想我知道为什么第一个对象空了

答案 1 :(得分:0)

我猜测到实际值的映射没有正确完成,例如user_id的值未标记为已选中,在options_for_select中您必须将所选值添加为参数(请参阅documentation)。

然而,有一个更简单的版本:

<%= f.collection_select(:user_id, User.all, :id, :email) %>

BTW使用类似simple_form的宝石也可以使建筑形式更直观,更直接。