如何将两个属性作为 text_method 传递给 rails 中的 collection_select
Posted
技术标签:
【中文标题】如何将两个属性作为 text_method 传递给 rails 中的 collection_select【英文标题】:How to pass two attributes as the text_method to a collection_select in rails 【发布时间】: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
但这是最好的方法吗?如果是这样,定义它的合适位置是什么?该模型?还是应该在助手中?如果是助手,应该在应用助手中吗?
【问题讨论】:
【参考方案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_method
和text_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 循环。这是我所问问题的要点,但我认为现在我将坚持将其定义为模型中的一种方法。这对我来说似乎比在视图中有那么多逻辑更清晰。但非常感谢您对这个问题的看法。以上是关于如何将两个属性作为 text_method 传递给 rails 中的 collection_select的主要内容,如果未能解决你的问题,请参考以下文章
如何将本地 Maven m2 作为属性传递给 Gradle?