我一直在看这里的其他一些答案,但似乎他们都错过了实现的部分,它指定了在回复者中仅出现 的回复,并回复了用户的提要。即他们的实施有回复显示在回复者的追随者的饲料上。
我一直在尝试使用范围和给定SQL子选择的修改的组合来实现解决方案。由于Feed无法正常渲染,我遇到了麻烦。
我的回复流程:回复被归类为以“@ userid#-user-name-separated-by-dashes-instead-of-spaces”开头的帖子。微博控制器调用模型扫描其内容以进行回复,并将to_id设置为回复所针对的用户的用户ID号。默认情况下,to_id设置为0.
在User控制器的feed def中,然后我调用一个范围来获取其to_id匹配传入的用户id的微博。这将检索对相关用户的所有回复。然后,我调用修改后的SQL子选择,该子选择仅从后续用户获取也将to_id设置为0的帖子 - 即帖子不是回复。
我不确定User模型中的实现是否正确(调用范围,然后调用SQL子选择 - 也许这不适用于视图的设计方式?)。
目前,回复的用户没有看到回复。 SQL子选择似乎也被打破 - 用户没有收到他们关注的任何用户的帖子。我改变的单行是
where("user_id IN (#{followed_user_ids} AND to_id = 0) OR user_id = :user_id"
这
where("user_id IN (#{followed_user_ids}) OR user_id = :user_id"
我的测试也无法解决问题。测试是:
当我手动执行此操作时,帖子会显示在用户3的主页上,但由于某种原因,测试失败(项目#4)。用户2的测试通过,用户1的测试未通过。
我只包含了我修改过的代码。其他一切都是根据Hartl的教程。
Microposts控制器:
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
@micropost.set_to_id
flash[:success] = "Micropost created!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
Microposts模型:
class Micropost < ActiveRecord::Base
include ApplicationHelper
belongs_to :user
default_scope -> { order('created_at DESC') }
scope :get_replies, ->(user) { where({ to_id: user.id }) }
validates :content, presence: true, length: { maximum: 140 }
validates :user_id, presence: true
# Returns microposts from the users being followed by the given user.
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids} AND to_id = 0) OR user_id = :user_id",
user_id: user.id)
end
# Sets to_id
def set_to_id
user_name = self.content
if user_name.index("-") != nil
if user_name[0..user_name.index('-')].match(/@\S+-/)
self.update(to_id: user_name[1..user_name.index('-')-1].to_f)
end
end
end
end
用户模型:
def feed
Micropost.get_replies(self)
Micropost.from_users_followed_by(self)
end
试验:
describe "replies" do
let(:second_user) { FactoryGirl.create(:user) }
let(:third_user ) { FactoryGirl.create(:user) }
let(:post1) { FactoryGirl.create(:micropost, user: third_user, content: "#{user_name_reply(user)}") }
before { second_user.follow!(third_user) }
it "should show the reply post on the replied to user's homepage" do
visit root_path
expect(page).to have_content(post1.content)
end
it "should show the reply post on the replier's homepage" do
click_link "Sign out"
visit signin_path
fill_in "Email", with: third_user.email
fill_in "Password", with: third_user.password
click_button "Sign in"
visit root_path
expect(page).to have_content(post1.content)
end
it "should not show the reply post on any other pages" do
click_link "Sign out"
visit signin_path
fill_in "Email", with: second_user.email
fill_in "Password", with: second_user.password
click_button "Sign in"
visit root_path
expect(page).not_to have_content(post1.content)
end
end
申请助手:
# Returns the user name in correct reply format ex: "Michael Hartl" -> "@1-michael-hartl"
def user_name_reply(user)
downcased_name = user.name.downcase
prefix_string = "@" + user.id.to_s + "-"
# if there are no spaces
if downcased_name.match(/\s/) == nil
return prefix_string + downcased_name
end
# create a name string ex: "Michael Hartl" -> "michael-hartl"
name_string = ""
str_index = 0
while downcased_name.index(' ', str_index) != nil
name_string = name_string + downcased_name[str_index..downcased_name.index(' ') - 1] + "-"
str_index = downcased_name.index(' ') + 1
end
name_string = name_string + downcased_name[str_index..downcased_name.length - 1]
return prefix_string + name_string
end
请停下来,