如何在Rails中使用表单助手并带有计数器

huangapple go评论62阅读模式
英文:

How to set rails form helper with counter

问题

我的模型结构如下:

<CheckBreak id: 1, procedure_id: "1", br_typ_id: 1, 
lok_typ: nil, lok_nr: nil, log_gestellnr: nil, auftrag: nil, 
bemerkungen: nil, date1: nil, pruefer: nil, sachkundiger: nil, 
freigeber: nil, lok_bremse_soll: nil, lok_bremse_ist: nil, 
zug_bremse_soll: nil, zug_bremse_ist: nil, einzeldruck: nil, 
dauerdruck: nil, c1_nr: nil, c1_point: nil, c1_io: nil, c1_nio: nil,
c1_inst_io: nil, c1_date: nil, c1_users: nil, c2_nr: nil,
c2_point: nil, c2_io: nil, c2_nio: nil, c2_inst_io: nil, 
c2_date: nil, c2_users: nil, c3_nr: nil, c3_point: nil, c3_io: nil, 
c3_nio: nil, c3_inst_io: nil, c3_date: nil, c3_users: nil, 
c4_nr: nil, c4_point: nil, c4_io: nil, c4_nio: nil, c4_inst_io: nil, 
c4_date: nil, c4_users: nil, c5_nr: nil, c5_point: nil, c5_io: nil, 
c5_nio: nil, c5_inst_io: nil, c5_date: nil, c5_users: nil, 
c6_nr: nil, c6_point: nil, c6_io: nil, c6_nio: nil, c6_inst_io: nil, c6_date: nil, c6_users: nil, c7_nr: nil, c7_point: nil, c7_io: nil, 
c7_nio: nil, c7_inst_io: nil, c7_date: nil, c7_users: nil, 
c8_nr: nil, c8_point: nil, c8_io: nil, c8_nio: nil, c8_inst_io: nil, 
c8_date: nil, c8_users:...

现在我将使用一个计数器变量编写我的Rails表单代码,就像这样:

<% counter = 1%>

    <tr>
      <td><%= form.check_box :"<%=counter%>_io"%> </td>
      <td class="th-sm" align=center><%= form.check_box :c1_nio%></td>
      ...
    </tr>

    <% counter += 1%>

如何做到这一点?这种代码缩减有没有名称?

我找到了一个非常不雅的解决方案。这个术语叫做迭代。

我可以在表单中使用纯HTML标记与嵌入的Ruby代码:

    <input type="text" name="check_break[c<%=counter%>_users]" id="check_break_c<%=counter%>_users">

但这太丑陋,感觉不对劲。

我需要考虑我的数据库模型架构。我将在新帖子中提出这个问题。

英文:

my Model structur is:

<CheckBreak id: 1, procedure_id: "1", br_typ_id: 1, 
lok_typ: nil, lok_nr: nil, log_gestellnr: nil, auftrag: nil, 
bemerkungen: nil, date1: nil, pruefer: nil, sachkundiger: nil, 
freigeber: nil, lok_bremse_soll: nil, lok_bremse_ist: nil, 
zug_bremse_soll: nil, zug_bremse_ist: nil, einzeldruck: nil, 
dauerdruck: nil, c1_nr: nil, c1_point: nil, c1_io: nil, c1_nio: nil,
c1_inst_io: nil, c1_date: nil, c1_users: nil, c2_nr: nil,
c2_point: nil, c2_io: nil, c2_nio: nil, c2_inst_io: nil, 
c2_date: nil, c2_users: nil, c3_nr: nil, c3_point: nil, c3_io: nil, 
c3_nio: nil, c3_inst_io: nil, c3_date: nil, c3_users: nil, 
c4_nr: nil, c4_point: nil, c4_io: nil, c4_nio: nil, c4_inst_io: nil, 
c4_date: nil, c4_users: nil, c5_nr: nil, c5_point: nil, c5_io: nil, 
c5_nio: nil, c5_inst_io: nil, c5_date: nil, c5_users: nil, 
c6_nr: nil, c6_point: nil, c6_io: nil, c6_nio: nil, c6_inst_io: nil, c6_date: nil, c6_users: nil, c7_nr: nil, c7_point: nil, c7_io: nil, 
c7_nio: nil, c7_inst_io: nil, c7_date: nil, c7_users: nil, 
c8_nr: nil, c8_point: nil, c8_io: nil, c8_nio: nil, c8_inst_io: nil, 
c8_date: nil, c8_users:......

Now i will write my rails form code with a counter var.

like this

<% counter = 1%>
 
    <tr>
      <td><%= form.check_box : <%=counter%>_io%> </td>
      <td class="th-sm" align=center><%= form.check_box :c1_nio%></td>
      ...
    </tr>

    <% counter += 1%>`

How can i do this?
Is there an name for this kind of code reduction?

I found a very dirty solution.
The term called iteration

i can use in the form pure html tags with embeded ruby

    <input type="text" name="check_break[c<%=counter%>_users]" id="check_break_c<%=counter%>_users">

But this is so ugly and it feels so wrong.

i have to consider my DB-Model architecture. I will start a new post to that Question.

答案1

得分: 1

以下是翻译好的部分:

While you could generate the inputs dynamically with something like:
虽然你可以像这样动态生成输入:

Your gut feeling that something is off is very right. Having an insane number of columns and potential nulls per row is not a viable solution.
你的直觉是正确的。每行具有大量列和潜在的空值不是可行的解决方案。

Instead normalize the data and think of it in terms of tables with relations between them:
相反,对数据进行规范化,并考虑它与它们之间的关系表。

# make sure you set the correct types and choose a name that matches your domain
rails g model thing check_break:references nr point io nio inst_io date user
# 确保设置正确的类型并选择与您的域匹配的名称
rails g model thing check_break:references nr point io nio inst_io date user
Then create a one to many association:
然后创建一对多关联:

class CheckBreak < ApplicationRecord
  has_many :things
  accepts_nested_attributes_for :things
end
class CheckBreak < ApplicationRecord
  has_many :things
  accepts_nested_attributes_for :things
end
class Thing < ApplicationRecord
  belongs_to :check_break
end
class Thing < ApplicationRecord
  belongs_to :check_break
end
And then use `fields_for` to create nested inputs for each nested record:
然后使用 `fields_for` 为每个嵌套记录创建嵌套输入:

<%= form.fields_for(:things) do |thing_form| %>
  <%= thing_form.label :nio %>
  <%= thing_form.check_box :nio %>
  # ...
<% end %>
<%= form.fields_for(:things) do |thing_form| %>
  <%= thing_form.label :nio %>
  <%= thing_form.check_box :nio %>
  # ...
<% end %>
This will automatically result in an array of hashes in the `params[:things_attibutes]` attribute.
这将自动在 `params[:things_attibutes]` 属性中生成哈希数组。

def check_break_params
  params.require(:check_break)
        .permit(
          :foo,
          :bar,
          things_attibutes: %i[nr point io nio inst_io date user]
        )
end
def check_break_params
  params.require(:check_break)
        .permit(
          :foo,
          :bar,
          things_attibutes: %i[nr point io nio inst_io date user]
        )
end
See [Rails Guides: Building Complex Forms][1].
参见 [Rails Guides: Building Complex Forms][1]
英文:

While you could generate the inputs dynamically with something like:

<%= 1.upto(9).each do |number| %>
  <%= form.label :"c#{number}nio" %>
  <%= form.check_box :"c#{number}nio" %>
  # ...
<%= end %>

Your gut feeling that something is off is very right. Having an insane number of columns and potential nulls per row is not a viable solution.

Instead normalize the data and think of it in terms of tables with relations between them:

# make sure you set the correct types and choose a name that matches your domain
rails g model thing check_break:references nr point io nio inst_io date user

Then create a one to many assocation:

class CheckBreak < ApplicationRecord
  has_many :things
  accepts_nested_attributes_for :things
end

class Thing < ApplicationRecord
  belongs_to :check_break
end

And then use fields_for to create nested inputs for each nested record:

<%= form.fields_for(:things) do |thing_form| %>
  <%= thing_form.label :nio %>
  <%= thing_form.check_box :nio %>
  # ...
<% end %>

This will automatically result in an array of hashes in the params[:things_attibutes] attribute.

def check_break_params
  params.require(:check_break)
        .permit(
          :foo,
          :bar,
          things_attibutes: %i[nr point io nio inst_io date user]
        )
end

See Rails Guides: Building Complex Forms.

huangapple
  • 本文由 发表于 2023年2月6日 16:44:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359049.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定