jquery - Rails ajax 前置事件

标签 jquery ruby-on-rails ajax

在我的应用程序中,我有一个状态模型,它还会在创建状态时创建一个事件项。我的事件模型是多态的,属于多个不同的模型。一切工作正常,但我在创建 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/

相关文章:

php - 如何在 php 中引用 HTML 元素?

java - 无法使用jsp将数据插入mysql

javascript - 使链接在完全显示时可点击

ruby-on-rails - 使用 Active Record 搜索嵌套/多级 Postgres JSON 类型

ruby-on-rails - 如何使用 coffeescript 获取当前年份

html - 如何在 Windows IE 中单击时生成文件 'download'

javascript - 是否有 AJAX 或 JSON 接口(interface)来检索给定用户名的 stackoverflow.com userId?

javascript - 从 jquery 移动多选获取字符串放入数据库

javascript - 如何用JS在表格末尾添加行?

Jquery从右向左淡入淡出