在我的应用程序中,我有一个状态模型,它还会在创建状态时创建一个事件项。我的事件模型是多态的,属于多个不同的模型。一切工作正常,但我在创建 ajax 状态时遇到了麻烦。在用户的个人资料页面上有一个状态表和一个事件列表。我希望用户能够通过 ajax 创建状态并将相应的事件项目附加到列表中。我有什么想法可以做到这一点吗?提前致谢。
statuses_controller.rb
class StatusesController < ApplicationController
before_filter :authenticate_member!, only: [:index, :new, :create, :edit, :update, :destroy]
before_filter :find_member
before_filter :find_status, only: [:edit, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound do
render file: 'public/404', status: 404, formats: [:html]
end
def show
@status = Status.find(params[:id])
@commentable = @status
@comments = @commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
@comment = @commentable.comments.new
respond_to do |format|
format.html # show.html.erb
format.json { redirect_to profile_path(current_member) }
end
end
def new
@status = Status.new
@status.build_document
respond_to do |format|
format.html # new.html.erb
format.json { render json: @status }
format.js
end
end
def create
@status = current_member.statuses.new(params[:status])
respond_to do |format|
if @status.save
current_member.create_activity(@status, 'created')
format.html { redirect_to :back }
format.json
format.js
else
format.html { redirect_to profile_path(current_member), alert: 'Post wasn\'t created. Please try again and ensure image attchments are under 10Mbs.' }
format.json { render json: @status.errors, status: :unprocessable_entity }
format.js
end
end
end
def destroy
@activity = Activity.find_by_targetable_id(params[:id])
@commentable = @status
@comments = @commentable.comments
if @activity
@activity.destroy
end
if @comments
@comments.destroy
end
@status.destroy
respond_to do |format|
format.html { redirect_to profile_path(current_member) }
format.json { head :no_content }
end
end
private
def find_member
@member = Member.find_by_user_name(params[:user_name])
end
def find_status
@status = current_member.statuses.find(params[:id])
end
end
activities_controller.rb
class ActivitiesController < ApplicationController
before_filter :authenticate_member!
before_filter :find_activity, only: [:destroy]
def index
params[:page] ||= 1
@activities = Activity.for_member(current_member, params)
respond_to do |format|
format.html # index.html.erb
format.js
end
end
def destroy
@status = @activity.targetable
if @activity.targetable_type == 'Status'
@status.destroy
end
@activity.destroy
respond_to do |format|
format.html { redirect_to :back }
format.json { head :no_content }
format.js
end
end
def upvote
@activity = Activity.find(params[:id])
if current_member.voted_up_on? @activity
@activity.unliked_by current_member
else
@activity.liked_by current_member
end
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
private
def find_activity
@activity = current_member.activities.find(params[:id])
end
end
事件.rb
class Activity < ActiveRecord::Base
belongs_to :member
belongs_to :targetable, polymorphic: true
acts_as_votable
self.per_page = 36
def self.for_member(member, options={})
options[:page] ||= 1
following_ids = member.following_members.map(&:id).push(member.id)
where("member_id in (?)", following_ids).
order("created_at desc").
page(options[:page])
end
end
profiles/show.html.erb
<% if @activities.count > 0 %>
<div id="media_query_stream">
<div id="activity_stream_wrap">
<%= render :partial => "activities/activities", locals: { activity: @activity} %>
</div>
</div>
<% else %>
<div class="none_message">
No Posts Yet
</div>
<% end %>
事件/_activities.html.erb
<% @activities.each do |activity| %>
<%= render partial: "activities/#{activity.targetable_type.underscore}/#{activity.action}", locals: { activity: activity } %>
<% end %>
activities/status/_created.html.erb
<div id="" class="list_act_wrap status_fil">
<div class="act_status_top">
<span class="">
<%= avatar_profile_link activity.member, :class => "act_av", title: activity.member.full_name, alt: activity.member.full_name %>
</span>
<span class="act_name">
<%= link_to activity.member.user_name, profile_path(activity.member) %>
</span>
<span class="meta">
<%= time_ago_in_words(activity.targetable.created_at) %>
</span>
<span class="act_title stat">
wrote a new <%= link_to 'Status', status_path(activity.targetable_id) %>
</span>
</div>
<div class="act_content">
<%= Rinku.auto_link(activity.targetable.content_html).html_safe %>
</div>
</div>
我尝试通过 ajax 附加事件,如下所示:
statuses/create.js.erb
$("#activity_stream_wrap").prepend("<%= escape_javascript(render :partial => 'activities/status/created', :locals => {:activity => @activity}) %>");
$('#stat_count').html("280");
$('#status_form')[0].reset();
但它会抛出一个错误,例如:
undefined method `member' for nil:NilClass
**编辑**
这是我的 create_activity 方法,它在创建状态时实际创建相应的事件。如何访问已创建的事件以便附加它?
def create_activity(item, action)
activity = activities.new
activity.targetable = item
activity.action = action
activity.save
activity
end
最佳答案
如果你查看你的 statuses/create.js.erb ,你会像这样渲染你的部分:
$("#activity_stream_wrap").prepend("<%= escape_javascript(render :partial => 'activities/status/created', :locals => {:activity => @activity}) %>");
请注意,您在部分中传递了@activity,但是如果您查看状态 Controller 中的创建方法,您没有名为 @ 的实例变量事件
修复:
您需要创建您的事件并将其分配给您的实例变量,如下所示:
def create
@status = current_member.statuses.new(params[:status])
respond_to do |format|
if @status.save
@activity = current_member.create_activity(@status, 'created') # you weren't assigning it to your instance variable
format.html { redirect_to :back }
format.json
format.js
else
format.html { redirect_to profile_path(current_member), alert: 'Post wasn\'t created. Please try again and ensure image attchments are under 10Mbs.' }
format.json { render json: @status.errors, status: :unprocessable_entity }
format.js
end
end
end
关于jquery - Rails ajax 前置事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24727565/