我开发了一种解决方案,允许用户使用at.js在帖子中互相提及,并使用一个单独的类对象来跟踪帖子的更改。我遇到的问题是,在类内部时,我无法引用被提及的用户将其ID添加到通知对象。它完美地找到了带有'@'符号的用户,但是Notification.create()对象在nil:NilClass中途失败。我不知道在哪里放置通知,以获取对current_user和目标用户的访问权限。如何格式化我的代码,以获取对scope中current_user的访问以及Notification对象被通知的用户?
notification.rb
通知对象的预期值:
Notification.create(recipient: mentioned.user, actor_id: current_user.id, action: "mentioned you", notifiable: mentioned.user, content: post.body_text.truncate(50).to_s, link_to_content: post.id)
application.js
//= require jquery
//= require jquery.atwho
application.scss
//=require jquery.atwho
application_helper.rb
def markdown(text)
renderer = Redcarpet::Render::SmartyHTML.new(filter_html: true,
hard_wrap: true,
prettify: true)
markdown = Redcarpet::Markdown.new(renderer, markdown_layout)
markdown.render(sanitize(text)).html_safe
end
def markdown_layout
{ autolink: true, space_after_headers: true, no_intra_emphasis: true,
tables: true, strikethrough: true, highlight: true, quote: true,
fenced_code_blocks: true, disable_indented_code_blocks: true,
lax_spacing: true }
end
_post.html.erb
<li>
<span class="content"><%= markdown(post.content) %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
</span>
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" },
title: post.content %>
<% end %>
</li>
routes.rb
Rails.application.routes.draw do
get 'mentions', to: 'users#mentions'
end
users_controller.rb
def mentions
respond_to do |format|
format.json { render :json => Mention.all(params[:q]) }
end
end
posts.coffee
class @Post
@add_atwho = ->
$('#post_content').atwho
at: '@'
displayTpl:"<li class='mention-item' data-value='(${name},${image})'>${name}${image}</li>",
callbacks: remoteFilter: (query, callback) ->
if (query.length < 1)
return false
else
$.getJSON '/mentions', { q: query }, (data) ->
callback data
jQuery ->
Post.add_atwho()
post.rb
class Post < ActiveRecord::Base
after_create :add_mentions
def add_mentions
Mention.create_from_text(self)
end
end
mention.rb
class Mention
attr_reader :mentionable
include Rails.application.routes.url_helpers
def self.all(letters)
return Mention.none unless letters.present?
users = User.limit(10).where('username like ?', "#{letters}%").compact
users.map do |user|
{ image: user.profile.avatar.url(:feed_thumb), name: user.username }
end
end
def self.create_from_text(post)
potential_matches = post.body_text.scan(/@\w+/i)
potential_matches.uniq.map do |match|
mention = Mention.create_from_match(match)
next unless mention
post.update_attributes!(body_text: mention.markdown_string(post.body_text))
# notification fails to save here!
Notification.create(recipient: @mentionable.user, actor_id: post.user.id, action: "mentioned you", notifiable: @mentionable.user, content: post.body_text.truncate(50).to_s, link_to_content: post.id)
mention
end.compact
end
def self.create_from_match(match)
user = User.find_by(username: match.delete('@'))
UserMention.new(user) if user.present?
end
def initialize(mentionable)
@mentionable = mentionable
end
class UserMention < Mention
def markdown_string(text)
host = Rails.env.development? ? '127.0.0.1:3000' : 'https://nothing.net' # add your app's host here!
text.gsub(/@#{mentionable.username}/i,
"[**@#{mentionable.username}**](#{user_url(mentionable, host: host)})")
end
end
结束
服务器日志错误
Started POST "/posts" for 127.0.0.1 at 2019-02-25 16:25:00 -0500
Processing by PostsController#create as JS
Parameters: {"utf8"=>"✓", "post"=>{"body_text"=>"@cooler Ok. Send this to myself.", "photo_cache"=>""}, "commit"=>"Post"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
(0.0ms) BEGIN
Post Exists (2.0ms) SELECT 1 AS one FROM "posts" WHERE "posts"."hash_id" = $1 LIMIT $2 [["hash_id", "gai887Te1VwC"], ["LIMIT", 1]]
Post Create (2.0ms) INSERT INTO "posts" ("body_text", "user_id", "created_at", "updated_at", "hash_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["body_text", "@cooler Ok. Send this to myself."], ["user_id", 2], ["created_at", "2019-02-25 21:25:01.907985"], ["updated_at", "2019-02-25 21:25:01.907985"], ["hash_id", "gai887Te1VwC"]]
Post Load (0.0ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", 0], ["LIMIT", 1]]
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."username" = $1 LIMIT $2 [["username", "cooler"], ["LIMIT", 1]]
Post Update (1.0ms) UPDATE "posts" SET "body_text" = $1, "updated_at" = $2 WHERE "posts"."id" = $3 [["body_text", "[**@cooler**](http://127.0.0.1:3000/u/cooler) Ok. Send this to myself."], ["updated_at", "2019-02-25 21:25:01.919976"], ["id", 71]]
(1.0ms) ROLLBACK
Completed 500 Internal Server Error in 92ms (ActiveRecord: 7.0ms)
NoMethodError (undefined method `user' for nil:NilClass):
app/models/mention.rb:21:in `block in create_from_text'
app/models/mention.rb:16:in `map'
app/models/mention.rb:16:in `create_from_text'
app