12.3 the status feed
1. we need to get all the micropost of the users followed by current user.
Micropost.from_users_followed_by(user)
so we can write a test this method.
describe Micropost do
.
.
.
describe "from_users_followed_by" do
before(:each) do
@other_user = Factory(:user, :email => Factory.next(:email))
@third_user = Factory(:user, :email => Factory.next(:email))
@user_post = @user.microposts.create!(:content => "foo")
@other_post = @other_user.microposts.create!(:content => "bar")
@third_post = @third_user.microposts.create!(:content => "baz")
@user.follow!(@other_user)
end
it "should have a from_users_followed_by class method" do
Micropost.should respond_to(:from_users_followed_by)
end
it "should include the followed user's microposts" do
Micropost.from_users_followed_by(@user).should include(@other_post)
end
it "should include the user's own microposts" do
Micropost.from_users_followed_by(@user).should include(@user_post)
end
it "should not include an unfollowed user's microposts" do
Micropost.from_users_followed_by(@user).should_not include(@third_post)
end
end
end
2. since the feed it self lives in the user model, so we still need test for the user model:
describe User do
.
.
.
describe "micropost associations" do
.
.
.
describe "status feed" do
it "should have a feed" do
@user.should respond_to(:feed)
end
it "should include the user's microposts" do
@user.feed.should include(@mp1)
@user.feed.should include(@mp2)
end
it "should not include a different user's microposts" do
mp3 = Factory(:micropost,
:user => Factory(:user, :email => Factory.next(:email)))
@user.feed.should_not include(mp3)
end
it "should include the microposts of followed users" do
followed = Factory(:user, :email => Factory.next(:email))
mp3 = Factory(:micropost, :user => followed)
@user.follow!(followed)
@user.feed.should include(mp3)
end
end
.
.
.
end
end
3. the implemention of feed method is easy, we just defer to from_users_followed_by method.
def feed
Micropost.from_users_followed_by(self)
end
4. next we will implement this method:
the sql is like this:
SELECT * FROM microposts
WHERE user_id IN () OR user_id =
before, we have seen:
Microposts.where("user_id = ?", id)
here, it should be:
where("user_id in (#{following_ids}) or user_id = ?", user)
note
a. we omitte Micropost, since this method is inside the class.
b. we used the rails convention if using user instead of user.id.
so we need to map the following user ids into an array.
map method will rescue us here:
[1,2,3,4].map{|i| i.to_s}
since this structure is so common, ruby makes a shortcut for it:
[1,2,3,4].map(&:to_s)
so we can use:
User.first.following.map(&:id)
but rails make it more convenient,
User.first.following_ids
so, in the end, our method will look like this:
def self.from_users_followed_by(user)
following_ids = user.following_ids
where("user_id in (#{following_id}) or user_id = ?", user)
end
5. now it works!
but we can refactor it:
where method can take a hash as argument.
where(:user_id => user.following.push(user))
this is much more neater.
it works, but when a user is following 5000 users, it will fetch all the 5000 users, then get all the microposts of the 5000 users, this is not good, we will refactor it in next chapter.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.