开发者

Sending objects values as IN statement in Rails

I'm working on a Newsfeed action. I have active friendships and i would like to find the posts only of those friendships to create the newsfeed.

This is the code i currently have:

@active_friendships = current_user.active_friendships
@posts = Post.where({ :user_id => [5,8,16] }).order("created_at DESC") 

I don't know how to send the @active_friendships.user_id values to the IN in the second line. At the moment the code is only worked because it has hardcoded the user_id of my active friends (5,8,16).

(If i do a debug @active_friendships) i get the 3 objects with their ids, but i still don't know how to send them to the IN in the second line as the ids to look for.

-- 
- !ruby/object:Friendship开发者_如何学运维 
  attributes: 
    created_at: 2010-10-06 22:27:54.620007
    updated_at: 2010-10-07 00:19:10.329799
    id: 182
    user_id: 8
    status: 1
    friend_id: 5
  attributes_cache: {}

  changed_attributes: {}

  destroyed: false
  marked_for_destruction: false
  new_record: false
  previously_changed: {}

  readonly: false
- !ruby/object:Friendship 
  attributes: 
    created_at: 2010-10-07 19:13:10.617959
    updated_at: 2010-10-07 19:13:17.097514
    id: 192
    user_id: 16
    status: 1
    friend_id: 5
  attributes_cache: {}

  changed_attributes: {}

  destroyed: false
  marked_for_destruction: false
  new_record: false
  previously_changed: {}

  readonly: false
- !ruby/object:Friendship 
  attributes: 
    created_at: 2010-10-10 04:12:48.931120
    updated_at: 2010-10-10 04:12:56.960752
    id: 214
    user_id: 8
    status: 1
    friend_id: 5
  attributes_cache: {}

  changed_attributes: {}

  destroyed: false
  marked_for_destruction: false
  new_record: false
  previously_changed: {}

  readonly: false

Many thanks in advance


You can try this:

@posts = Post.where(:user_id => @active_friendships.map(&:friend_id)
                   ).order("created_at DESC"

But better way of implementing this is to add an association

class User
  has_many :active_friendships, :class_name => "Friendship", :conditions = {...}
  has_many :active_friend_posts, :through => :active_friendships, 
             :source => :friend_posts
end

class Friendship
  belongs_to :user
  belongs_to :friend, :class_name => "User"
  has_many   :friend_posts, :class_name => "Post", 
                :primary_key => :freind_id, :foreign_key => :post_id
end



class Post
  belongs_to :user
end

Now you can do the following:

current_user.active_friend_posts.order("created_at DESC") 


I'm new at this, but could you collect all of the Friendship.user_id's into an array and then pass that in the where clause?

@friends_userids = current_user.active_friendships.collect { |x| x.user_id }
@posts = Post.where({ :user_id => @friends_userids }).order("created_at DESC")


I had a similar issue. This is how I implemented it:

 ids = @active_friendships.map { |x| x.user_id }
 ids = ids.join(",")
 @posts = Post.all(:conditions => ["posts.user_id in (#{ids})"]).order("created_at DESC") 

This creates an array of all user IDs from @active_friendships and then joins them into a string with a comma as a separator. Then I simply passed this to the :conditions parameter.

It's not as elegant as I like but it works.

Hope this helps.


Rails has a special method for getting an array of associated ids. You should be able to do this in one line something like this:

@posts = Post.where(:user_id => current_user.active_friendship_ids).order("created_at DESC")

Whenever you're dealing with has_many and has_many :through relationships, you have access to the association_ids method, which won't return the full objects. Check out the full api here:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜