Rails - text_field 中的默认值但仅适用于 new_record?
在内容模型上有一个名为 slug
的属性。创建新记录时,我想使用助手来填充此字段,但在现有记录上我想使用数据库中的值。
目前我有:
<% if @content.new_record? %>
<%= f.text_field :slug, :value => "#{generate_slug(6)}" %>
<% else %>
<%= f.text_field :slug %>
<% end %>
但这似乎有点冗长。这是最好的方法,还是没有其他方法? (Rails 新手只是想在我不确定的问题上找到“Rails 方式”)
编辑
我应该注意到该帮助器当前位于 /app/helpers/application_helper.rb 已移至内容控制器中的私有操作。大卫的回答非常有效。
On a Content model have an attribute named slug
. When creating a new record, I want to use a helper to populate this field, but on an existing record I want to use the value from the database.
Currently I have:
<% if @content.new_record? %>
<%= f.text_field :slug, :value => "#{generate_slug(6)}" %>
<% else %>
<%= f.text_field :slug %>
<% end %>
But that seems a bit verbose. Is this the best way, or is there no other way? (Rails newb just trying to find the "Rails way" on issues I'm unsure of)
Edit
I should note that the helper is currently in /app/helpers/application_helper.rb Moved to be a private action in the Contents controller. David's answer worked great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在你的控制器中,
如果不存在,这将为
slug
属性分配一个值然后,在你的视图中,你可以简单地使用
In your controller
This will assign a value to the
slug
attribute if none is presentThen, in your view you can simply use
选项
遵循的例子。我正在打电话呢!
Options
Example to follow. I'm typing on phone!
我碰巧在我的项目中使用 jQuery,所以当我想要一些这样的功能时,我通常使用类似 标记。然后,我会使用类似
<%= f.text_field :slug, :title => generate_slug(6) %>
. (热门提示,如果 #generate_slug 返回的内容可以自行解析为字符串,则不需要将 #generate_slug 调用放入字符串内,事实上,如果不这样做,性能会更高。)如果您不希望要采用 jQuery 方法,您可能希望将这段逻辑包装在您的模型中。
如果它确实属于视图,还有一个选择是让你的 Ruby 更简洁一点(你必须判断这是否更具可读性):
不要忘记
(generate_slug(6) 周围的括号)如果@content.new_record?)
。如果这样做,if
将应用于 text_field,这不是您想要的。但还有更多方法可以做到这一点。如果您的逻辑可能会改变并且您将此代码粘贴到整个 Rails 项目中,那么上面的代码行就不太好。当我想向我的文本字段添加“必需”类但前提是它们是新记录时(我们有一些不想让人们清理的旧数据),我使用 < 创建了自己的表单生成器code>required_field 方法刚刚调用
text_field
并添加了一个“required”类(如果该项目是新记录)。这看起来像是一项工作,但我们有大约 20 种不同的表单,每种表单都可能有多个必填字段,而且在一个地方更改业务逻辑要容易得多。因此,如果您确实认为此逻辑属于视图,但您有大量这样的代码行,并且您不想在数百万处更改它,那么 FormBuilder 就是您的最佳选择。我认为在大多数情况下这比助手更漂亮、更合适,但同样,情人眼里出西施。这是我的代码,在某种程度上适合您的情况:希望在所有这些不同的方法中都有适合您的项目的方法。
I happen to use jQuery in my projects, so when I want some functionality like this, I usually use something like labelify. Then, I'd use something like
<%= f.text_field :slug, :title => generate_slug(6) %>
. (Hot tip, you don't need to put the #generate_slug call inside of a string if it returns something that will resolve to a string by itself, in fact it's more performant if you don't.)If you don't want to go with jQuery approach, you might want to wrap this piece of logic in your model.
If it really belongs in the view, still another option is to just make your Ruby a little bit more concise (you'll have to judge if this is more readable):
Don't forget the parens surrounding
(generate_slug(6) if @content.new_record?)
. If you do, theif
will be applied to the text_field, which is not what you want.But there are still more ways to do it. The above line of code isn't great if your logic might change and you're pasting this code all over your rails project. When I wanted to add a 'required' class to my text fields but only if they were a new record (we had some legacy data that we didn't want to make people clean up), I created my own form builder with a
required_field
method that just calledtext_field
and added a 'required' class if the item was a new record. This might seem like a work, but we have around 20 different forms, each with potentially multiple required fields, and it's a lot easier to change the business logic in one place. So if you really think this logic belongs in the view but you've got a ton of these lines of code and you don't want to have to change it in a million places, then FormBuilder is the way to go. I think this is in most cases prettier and more appropriate than a helper, but again, beauty is in the eye of the beholder. Here's my code somewhat adapted for your case:Hopefully in all of these different approaches is one that fits your project.