新手问题 嵌套表单 view 应该怎么设置?

chairy11 · 2014年11月27日 · 最后由 shinefine 回复于 2014年12月07日 · 2119 次阅读

(此图只针对一个用户,一个页面上有多个这样的区块) 有这样的需求,把部门用户的本月的加班明细列出来,每个人可能有一堆加班明细,如上图,然后,部门经理手工给予一个折合的天数。 目前的难题是,可以第一次审核正常生成所有结果,可是如果后面再想编辑,就无法提取已有的结果,而是只有新的表单,再填就会重复生成。

目前的代码如下:

  • model 中置好关联关系的, ```ruby class Monthly < ActiveRecord::Base
    has_many :monthly_overtimes, dependent: :destroy accepts_nested_attributes_for :monthly_overtimes, allow_destroy: true end

class MonthlyOvertime < ActiveRecord::Base belongs_to :staff, class_name: 'User', foreign_key: 'staff_id' belongs_to :reviewer, class_name: 'User', foreign_key: 'reviewer_id' belongs_to :monthly

validates :staff_id, :reviewer_id, :day_count, presence: true end

-  controller中也已经设置了
```ruby
def monthly_params
    params.require(:monthly).permit(:year, :month, :status,
                                    monthly_overtimes_attributes:[:id, :staff_id, :reviewer_id, :day_count, :_destroy])
 end
  • 在 view 中,对每个加班过的用户,先取出加班明细,再给一个新的表单 erb <section class="page_body"> <%= simple_form_for @monthly do |f| %> <%= f.error_notification %> <% @group_pw_by_user.each do |user, pws| %> <article> <table class="table table-hover scroll_table"> <thead> <tr> <th class="col-md-1">姓名</th> <th class="col-md-7">加班事由</th> <th class="col-md-1">加班日期</th> <th class="col-md-1">开始时间</th> <th class="col-md-1">结束时间</th> <th class="col-md-1">加班地点</th> </tr> </thead> <tbody> ...此处为提取的加班明细的条目 </tbody> <tfoot> <%= f.simple_fields_for :monthly_overtimes,f.object.monthly_overtimes.build do |mot| %> <tr> <td></td> <td> <%= mot.input_field :staff_id, as: :hidden, value: pws[0].user.id %></td> <td><%= mot.input_field :reviewer_id, as: :hidden, value: current_user.id %></td> <td class="monthly_overtime_day_count"><div>折合天数</div></td> <td colspan="2"> <%= mot.input :day_count, wrapper: :input_group, label: false do %> <%= mot.input_field :day_count, min: '0.5', step: '0.5', label: false %> <span class='input-group-addon'>天</span> <% end %> </td> </tr> <% end %> </tfoot> </table> </article> <% end %> <div class="form-action"> <%= f.submit '提交', class: 'btn btn_lg btn-info pull-right', name:'submit', id:'submit_btn' %> </div> <% end %> </section>

如果我不用<%= f.simple_fields_for :monthly_overtimes,f.object.monthly_overtimes.build do |mot| %>中的,f.object.monthly_overtimes.build,那会造成两方面的后果:

  1. 第一次审核填写表单,为多个用户填写了多个折合数,但只有一个会被保存,因为生成 name 为"monthly[monthly_overtimes_attributes][day_count]",而不是加序号的"monthly[monthly_overtimes_attributes][11][day_count]"
  2. 如果提交过再 edit,在每个用户下面,它就会出现多项,也无法对应相应的用户

我想大概是我对 nest_form 的理解还不够深刻。 但我这种需求,会有方法实现吗?

Monthly 这个 model 有点多余,

而 MonthlyOvertime 这个 model 应该改名为‘员工加班信息’UserOvertime,对应表 UserOvertimes,表包含字段 UserID, month(integer)【月份】, day_count(integer)【折合天数】

User 直接 has_many UserOvertime, UserOvertime belongs_to User,部门经理在页面上填的每个员工的折合加班天数都可以直接对应写入 UserOvertime 这张表。

这样很简单就能解决你的问题吧。

至于员工的每月加班明细信息可以存于另一张表中。你应该已经有了这张表了。

#1 楼 @shinefine 不是的,这个 monthly 是指月报,有很多其它的统计指标关联着,所以 monthly 还是要保留的。,月报下面还有周报 weekly,weekly 下面有个人周报 personal_weekly,personal_weekly 下面有 overtimes(加班明细)。 当然你说直接建立 monthly_overtimes,增加一个 month 的字段去标记是哪个月,也是可以的。但即使是直接关联,不用 nest_attributes, 好像我还是想不到怎样在一个页面一个表格中,批量修改同一个 model 的 N 行数据。糊涂了。你有哪些资料可以推荐一下吗? 谢谢了:)

最最直接的方法就是:

在页面中,手动构造表单 (使用 form_tag ,不用 form_for ) 来提交针对批量 model 的修改信息,然后在对应的控制器的 action 中手动解析提交上来的数据,一条一条的查询出对应的 model 对象信息,新建/修改 相关的信息存入数据库。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号