Rails和ActiveRecord在处理我会考虑处理单个模型的极其简单的查询方面做得非常好。我现在有一种情况,我需要做一些稍微复杂的事情 - 但仍然是微不足道的 - 我不知道该怎么做。
我有一个User
has_many :images
。每个Image has_many :thumbnails
。
在我的/images
索引页面上,我实际上想要为属于登录用户的每个图像显示小缩略图。一个简单的查询,但因为这样做涉及多个表的条件,我不知道如何以真正的Rails方式处理它。我宁愿避免编写SQL并处理随之而来的麻烦。
我看到rails提供:joins
选项,但这似乎是一个非常优雅的事后想法。这是满足这种要求的最佳方式还是有一种我没有找到的更好的方法?
感谢。
更新:我被告知有关命名的范围,并且不得不承认现在对他们有一些非常不恰当的感受。这些允许相当复杂的条件非常优雅地应用大量的语法糖。例如,我可以在我的Image模型上为给定用户拥有的图像创建一个命名范围,并使其成为动态:
class Image < ActiveRecord::Base
named_scope :owned_by,
lambda {
|user_id| {
:conditions => { :user_id => user_id }
}
}
end
我还可以在我的缩略图模型上应用命名范围来指定小缩略图:
class Thumbnail < ActiveRecord::Base
named_scope :small, :conditions => { :name => 'Small' }
end
现在我可以把它们连在一起做一些非常强大的东西,它们可以很好地读取。在我的控制器中,我可以返回给定用户的所有图像:
@images = Image.owned_by( current_user )
在我看来,我想显示小缩略图,所以我们大力链接:
<% for image in @images %>
<tr>
<td><%= h( image.name ) %></td>
<td><%= link_to( image_tag( image.thumbnails.small.first.binary.uri, :alt => h( image.name ), :title => h( image.description ) ), :action => :show, :id => image.id ) %></td>
</tr>
<% end %>
查看image_tag
。对于每个图像,它识别第一个小缩略图,然后将其链接以检索其物理文件位置。这并不是我想要的,因为它需要为每个图像额外的数据库命中,但它可能更准确地满足我在这个特定实例中的需求。
答案 0 :(得分:3)
RailsGuides总是很方便,我花了很多时间在那里。
查看has_many:through assocation,它允许Images模型连接这些表并允许与Image相关的其他字段。
Thumbnail
has_many :images
has_many :users, :through => :images
Image
belongs_to :user
belongs_to :thumbnail
User
has_many :images
has_many :thumbnails, :through => :images
然后在访问与您可以执行的用户相关的缩略图时;
@user.thumbnails
或者缩略图应该有一个图像和一个用户?
Thumbnail
belongs_to :image
Image
belongs_to :user
has_one :thumbnail
User
has_many :images
has_many :thumbnails, :through => :images
答案 1 :(得分:2)
要精美地编写复杂查询,您还可以使用像松鼠这样的东西。 Squirrel是一个插件,允许您以更自然的方式编写复杂的查询:
User.find(:all) do
first_name == "Jon" # first_name = 'Jon'
email =~ "%@thoughtbot.com" # email LIKE '%@thoughtbot.com'
created_at >= 4.years.ago # created_at >= '2004-06-27 10:34:22'
awesomeness <=> (1..10) # awesomeness BETWEEN 1 AND 10
banned_since == nil # banned_since IS NULL
end
您甚至可以使用关联(这是您需要的):
Post.find(:all) do
user.first_name.contains? "Jon"
end
Squirrel - Natural Looking Queries for Rails的更多信息。另外,请务必查看Github上的维基页面。
答案 2 :(得分:0)
对于特定用户,您可以通过执行此类操作找到所有缩略图
@user = User.find(:id, :include => :thumbnails)
:必须在用户模型中定义缩略图,因为他的答案中显示了像revgum这样的关联。