【问题标题】:How to pass two attributes as the text_method to a collection_select in rails如何将两个属性作为 text_method 传递给 rails 中的 collection_select
【发布时间】:2021-10-04 13:17:36
【问题描述】:

我有一个collection_select,它的rails 形式如下所示:

<%= form.collection_select :post_id, Post.all, :id, :title, {}, { class: "mt-1 block" } %>

我似乎无法从 docs 或谷歌搜索中弄清楚,如何将多个属性从 Post 传递到下拉列表,以便用户看到的不仅仅是 :title。像这样的:

<%= form.collection_select :post_id, Post.all, :id, :title + :category, {}, { class: "mt-1 block" } %>

我可以创建一个自定义方法传递给text_method,例如Post 模型中的:title_with_category,例如:

<%= form.collection_select :post_id, Post.all, :id, :title_with_category, {}, { class: "mt-1 block" } %>

Post.rb:

def title_with_category
  self.title + " " + self.category
end

但这是最好的方法吗?如果是这样,定义它的合适位置是什么?该模型?还是应该在助手中?如果是助手,应该在应用助手中吗?

【问题讨论】:

    标签: ruby-on-rails ruby forms collection-select


    【解决方案1】:

    首先,如果其中一项为 nil,这样做会更安全:

    Post.rb

    def title_with_category
      "#{title} #{category}"
    end
    

    接下来是您的选择。在控制器中,将选项作为属性返回:

    def new
      @post_options = Post.all.collect{|post| [post.id, post.title_and_category]}
      # OR
      @post_options = Post.all.collect{|post| [post.id, "#{post.title} #{post.category}"]}
      # you can skip the model method with the second option
    end
    

    在表格上:

    <%= form.select :post_id, @post_options, {}, { class: "mt-1 block" } %>
    

    form select

    【讨论】:

    • 这个答案中唯一有意义的部分是使用插值而不是串联。手动创建选项的整个步骤是完全多余的。
    • #{post.title} #{post.category} Tom 的好点子。感谢您指出了这一点。我认为我更愿意在模型中执行此操作,而不是将发布选项收集到实例变量中,但感谢您对此的看法。
    【解决方案2】:

    您可以为value_methodtext_method 参数传递一个可调用的collection_select

    <%= form.collection_select :post_id,
                               Post.all,
                               :id, # value_method
                               ->(p){ "#{p.title} #{p.category}" }, # text_method
                               {},
                               { class: "mt-1 block" }
    %>
    

    可调用对象是响应call 方法的任何对象,例如 lamdba 和 proc 对象。

    循环的每次迭代都会在帖子中调用它。

    定义这个的合适的地方是什么?该模型?还是应该在助手中?如果是助手,应该在应用助手中吗?

    如果您选择将其提取到单独的方法中,则没有明确的答案。该模型将是最简单的解决方案,但您也可以争辩说应该将表示逻辑与业务逻辑分开,并且模型已经承担了很多责任。

    我认为我们都同意 ApplicationHelper 是最不合适的选择,除非您只是打算将代码扔进垃圾抽屉。

    此代码可以进入 Post、PostHelper、PostPresenter(如果您使用装饰器模式)或自定义表单构建器(这似乎有点矫枉过正)。

    【讨论】:

    • 谢谢马克斯。没有考虑过使用这样的 lambda 循环。这是我所问问题的要点,但我认为现在我将坚持将其定义为模型中的一种方法。这对我来说似乎比在视图中有那么多逻辑更清晰。但非常感谢您对这个问题的看法。
    猜你喜欢
    • 2016-04-02
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多