问题
I have established a Twitter-like @replies that allows users to contact one another through user dailyposts...similar to stackoverflow's.
Using this as a guide https://github.com/kltcalamay/sample_app/compare/original-version...master
How can I parse/scan a post & then replace the @usernames with the link to that users page
EXAMPLE of a post.
Kevins Post:
@Pzpcreations @john @steve hey everyone lets all hang out today
I want scan/parse the post and then link the users @Pzpcreations @john @steve to their profile
I tried creating a method in my Dailypost Model, that stores the usernames in an array....but IDK how to replace and link them to the appropriate users page
def username_link
str = self.content_html
recipient = str.scan(USERNAME_REGEX)
end
This gives me ["@Pzpcreations", "@john", "@steve"]
Please help me out....new to rails :)
MODELS
class Recipient < ActiveRecord::Base
attr_accessible :dailypost_id, :user_id
belongs_to :user
belongs_to :dailypost
end
class User < ActiveRecord::Base
attr_accessible :name, :email, username
has_many :dailyposts, dependent: :destroy
has_many :replies, :class_name => 'Recipient', :dependent => :destroy
has_many :received_replies, :through => :replies, :source => 'dailypost'
end
class Dailypost < ActiveRecord::Base
attr_accessible :content, :recipients
belongs_to :user
###What is the Correct REGEX for Rails 4?
USERNAME_REGEX = /@\w+/i
has_many :recipients, dependent: :destroy
has_many :replied_users, :through => :recipients, :source => "user"
after_save :save_recipients
**private**
def save_recipients
return unless reply?
people_replied.each do |user|
Recipient.create!(:dailypost_id => self.id, :user_id => user.id)
end
end
def reply?
self.content.match( USERNAME_REGEX )
end
def people_replied
users = []
self.content.clone.gsub!( USERNAME_REGEX ).each do |username|
user = User.find_by_username(username[1..-1])
users << user if user
end
users.uniq
end
end
SCHEMA
create_table "recipients", :force => true do |t|
t.string "user_id"
t.string "dailypost_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
[#<Recipient id: 7, **user_id: "103"**, dailypost_id: "316", created_at: "2013-06-18
10:31:16", updated_at: "2013-06-18 10:31:16">]
User_ID in recipients are the users that are mentioned in the Dailypost.
VIEWS
<%= link_to dailypost.username_link %>
回答1:
You can pass each match through to a block. In this block you return the link required, something like
def username_link
str = self.content_html
str.gsub!(USERNAME_REGEX).each do |recipient|
if User.find_by_name(recipient)
"[link to #{recipient}]"
else
recipient
end
end
end
Edit
Create a helper function in app/helpers/posts_helper.rb
def post_with_links(post)
post.content_html.gsub(/@\w+/).each do |username|
user = User.find_by_username(username[1..-1])
if user
link_to username, user
else
username
end
end
use this in your view
<%= post_with_links(post) %>
回答2:
You're looking to do a find and replace on each user name, and also generating the link to the user's profile. It would look something like this:
def username_link
new_content_html = self.content_html
recipients = new_content_html.scan(USERNAME_REGEX)
recipients.each do |recipient|
user = User.find_by_username(recipient) # strip off the @ if required
new_content_html.gsub!(recipient, "<a href='#{users_path(user)}'>#{user.username}</a>")
end
new_content_html
end
This assumes you've got a route for users
in your route file which generates the users_path
method.
There's a whole rabbit hole of additional things to talk about as it regards a twitter like reply system and discovering those on your own is going to be half the fun! ;)
来源:https://stackoverflow.com/questions/17222033/parse-a-post-for-username