Rails Ruby 数组 Nil && []
为什么某些查询返回带有 [] 和一些 Nil 的记录?
我试图弄清楚为什么如果我运行这样的语句:
user.articles # yields '[]' if the user has no articles
但是如果我写这样的语句:
user.likes # yields Nil if empty
likes将是用户模型中的一个方法,并且看起来像这样:
def likes
Likes.find_by_user_id(id)
end
Likes将是一个包含user_id和article_id的连接表。
在我看来,我想做的是做出这样的陈述:
user.likes.count
实际上,现在我想到了,这样做会很棒:
@user.articles.likes
并获取用户喜欢的一系列文章。
有道理吗?
我感觉这需要在我的模型中使用 :through 参数,但我还没有掌握这一点,也不知道它是否合适。
Why do certain queries return records with [] and some Nil?
I am trying to figure out why if I run a statement like:
user.articles # yields '[]' if the user has no articles
but if I write a statement like this:
user.likes # yields Nil if empty
likes would be a method in the User model and would look something like this:
def likes
Likes.find_by_user_id(id)
end
Likes would be a join table containing a user_id and article_id.
What I'd like to do in my view is make these sort of statements:
user.likes.count
Actually now that I think of it, it would be great to do this:
@user.articles.likes
and get a array of the articles that a user likes.
Make sense?
I'm getting the feeling that this calls for a :through parameter in my models, but I haven't gotten the hang of that yet, and don't know if it's appropriate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
返回一条记录的方法在不匹配时返回 nil。那些本来应该返回许多记录的记录却返回一个空集合。
The methods that are meant to return one record return nil when not matching. The ones that are meant to return many records return an empty collection, instead.
这是因为当没有结果时,空集合就是空对象。换句话说,如果我要求您提供一个包含以字母“x”开头的所有状态的数组,您会给我一个空数组。这对应于文章的第一个示例,该方法可能通过在模型中声明 has_many(:articles) 来编写。这是一个记录的集合,就像以“x”开头的州是一个州的集合一样。所以它返回一个空数组。
但如果我要求以字母 x 开头的一个状态,你会给我什么?你不能给我一个空数组,因为它代表一个集合。您需要一个代表“无”的对象。这样的对象是存在的,它被称为nil。
顺便说一句,通常你的模型是单一的(
Like
而不是Likes
),并且 find 方法应该返回该 id 的所有 Like,而不仅仅是第一个。It's because an empty collection is the null object when there are no results. In other words, if I asked you for an array with all the states in them that begin with the letter "x", you would give me an empty array. This corresponds to the first example of articles, a method probably written by declaring a has_many(:articles) in your model. This is a collection of records, just as the states beginning with "x" is a collection of states. So it returns an empty array.
But if I asked for the one state that begins with the letter x, what would you give me? You can't give me an empty array, because that represents a collection. You need an object that represents "nothing". Such an object exists, it's called nil.
BTW, usually your models are singular (
Like
rather thanLikes
), and the find method should return all the likes for that id, not just the first one.虽然 Virtuals 答案可行,但您应该阅读有关 ActiveRecord 关系的内容。您的场景可以这样设置:(只是一个粗略的草图,省略细节)
这将为您提供您想要的大部分功能(以及更多)
更新
我通过添加了 has_many ,这使得更多感觉并且应该更适合你。
我不太喜欢这里的命名,因为您现在可以访问 @user.articles 之类的内容,它将使用定义的关联。通常 @user.articles 意味着文章与用户直接相关(有自己的 user_id 字段)。你可以使用类似的东西
,然后使用
但这将需要更多的信息,因为你必须显式地告诉 Rails id 字段的名称(所以这不会像我编写的代码那样工作,只是暗示有更多选项)
通过使用作用域或新的 Rails 3.x 查询语法(如 @user.where(...)),可以提供更多选项,如果您需要链接多个条件,则可以更轻松地工作。
一般来说,我建议使用 has_many 和 Belongs_to 之类的关联设置尽可能多的信息,因为这样 Rails 就可以免费为您提供许多功能,否则您将无法获得这些功能。但是这样做或那样做的原因可能有很多,因此在编程中通常没有 100% 适合每种情况的答案。
While Virtuals answer would work, you should read about ActiveRecord relationships. Your scenario could be setup like this: (just a rough sketch, leaving out details)
This would give you most of the functionality you want (and much more)
Update
I added the has_many through, which makes more sense and should work better for you.
I don't exactly like the naming here, since you now can access something like @user.articles, which would use the defined associations. Normally @user.articles would mean, that the articles are directly related to the user (have a user_id field of their own). You could use something like
and then use
But this would require even more information, since you would have to tell Rails the names of the id fields explicitly (so this won't work exactly like I wrote the code, just a hint that there are more options)
There are even more options by using scopes or the new Rails 3.x query syntax like @user.where(...), which works easier if you need to chain several conditions.
In general I would recommend to set up as many information as possible with associations like has_many and belongs_to, since this way Rails gives you a lot of functionality for free, that you won't get otherwise. But there may be many reasons to do it this or that way, so as often in programming there is no 100% answer that fits every situation.