• @libuchao 正解,非常感谢~~

  • @insua 谢谢你的指导,我现在还是在本地呢,还没有上传到服务器。

  • @huacnlee 好的,谢谢李哥。我的用户名也有 DOM 标记,我看了下 homeland 的代码。好像当前页面(本地)的用户,您好像是直接获取用户名、用户图片等信息的。

    代码:

    Homeland 的 app.coffee

    scanMentionableLogins: (query) ->
      result = []
      logins = []
      for e in query
        $e = $(e)
        item =
          login: $e.find(".user-name").first().text()
          name: $e.find(".user-name").first().attr('data-name')
          avatar_url: $e.find(".avatar img").first().attr("src")
        continue if not item.login
        continue if not item.name
        continue if logins.indexOf(item.login) != -1
    
        logins.push(item.login)
        result.push(item)
    
      console.log result
      _.uniq(result)
    
    mentionable : (el, logins) ->
      logins = [] if !logins
      $(el).atwho
        at : "@"
        limit: 8
        searchKey: 'login'
        callbacks:
          filter: (query, data, searchKey) ->
            return data
          sorter: (query, items, searchKey) ->
            return items
          remoteFilter: (query, callback) ->
            r = new RegExp("^#{query}")
            # 过滤出本地匹配的数据
            localMatches = _.filter logins, (u) ->
              return r.test(u.login) || r.test(u.name)
            # Remote 匹配
            $.getJSON '/search/users.json', { q: query }, (data) ->
              # 本地的排前面
              for u in localMatches
                data.unshift(u)
              # 去重复
              data = _.uniq data, false, (item) ->
                return item.login;
              # 限制数量
              data = _.first(data, 8)
    
              callback(data)
        displayTpl : "<li data-value='${login}'><img src='${avatar_url}' height='20' width='20'/> ${login} <small>${name}</small></li>"
        insertTpl : "@${login}"
      .atwho
        at : ":"
        limit: 8
        searchKey: 'code'
        data : window.EMOJI_LIST
        displayTpl : "<li data-value='${code}'><img src='#{App.twemoji_url}/svg/${url}.svg' class='twemoji' /> ${code} </li>"
        insertTpl: "${code}"
      true
    

    我希望的是:用 DOM 标记获取当前用户的名称,然后通过mentionable() 函数,把当前页面 用户名的数组传到users_controller中的mentions动作,再通过查询用户数据库,返回用户的其他相关的信息。但是实际上,我现在获取到的用户名数组,不能传到 mentions动作,但是我不知道,我现在的问题时出现在哪里了?

    非常感谢您的帮助~

  • @ThxFly 我在浏览器里已经可以获得了错误信息,但是怎么用 ajax 来显示呢?谢谢

  • @ThxFly 谢谢你的提醒,已更正了,但是现在又提示错误: Uncaught TypeError: res.error is not iterable,请问该怎么做呢?非常感谢。

  • @Rei 非常感谢,我试了 pdf doc xlsl epub chm 格式的文件,除了 pdf,其余的格式都能直接下载。pdf 格式的是在线打开,这是浏览器的问题吧?再次感谢 Rei.

  • @shinetech_wh 你好,新手可以吗?我自学的有一段时间了,基本熟悉前后端开发,但是不够精通。

  • @huacnlee 谢谢您的回复。我没有用过 will_paginate 呢,用的就只有Kaminari

    然后,我的错误是:我通过index.html.erb中的 <%= paginate @notifications.page(params[:page]).per(10),left:2,right:1,window: 1 %> 点击@notifications 直接进入的norifications_controller.rb为: /Users/hs/.rvm/gems/ruby-2.5.0/gems/notifications-0.6.0/app/controllers/notifications/notifications_controller.rb😓

    然后,我一直是在这里修改的。。。我然后在

    app/controllers/notifications/notifications_controller.rb 修改 index action 为:

    @notifications = notifications.includes(:actor).order("id desc").page(params[:page]). 现在可以分页正常了。

  • @Rei 非常感谢大佬的指点。

  • @Rei 请问下大哥:

    class ReportsController < ApplicationController
      before_action :logged_in_user
      before_action :get_target
    
      def new
        @report = Report.new
        respond_to do |format|
          format.html do
            redirect_to @report_url
          end
          format.js
        end
      end
    
      def create
        @report = Report.new report_params.merge(reporter_id: current_user.id)
    
        if @report.save
          redirect_to @report_url
        else
          redirect_to home_path
        end
      end
    
      def destroy
        @report = Report.find(params[:id])
        @report.destroy
      end
    
      private
    
      def get_target
        @report_type = params["reportable_type"]
        @report_id = params["reportable_id"]
        report_able = Comment.find_by_id(@report_id.to_i)
        target_able_type = report_able.commentable_type.singularize.classify.constantize
        target_able_id = report_able.commentable_id.to_i
        @report_url = target_able_type.find_by_id(target_able_id)
      end
    
      def report_params
        params.require(:report).permit(:reportable_type, :reportable_id,:content,:radio_content)
      end
    end
    
    

    我按照您的代码,如我在/questions/15页面(即当前页面),提交 report 后,想再次跳转到当前页面,该怎么做呢?

    在我的get_target action 中,如果按照 report_able = Comment.find_by_id(26) 那么@report_url 可以获取到正确的 url('/questions/15')。

    但是如果是 report_able = Comment.find_by_id(@report_id.to_i),使用变量的话,则会提示错误:

    
    127.0.0.1 - - [24/Aug/2018:00:36:11 CST] "GET /reports/new?reportable_id=26&reportable_type=Comment HTTP/1.1" 200 3584
    http://127.0.0.1:3000/questions/15 -> /reports/new?reportable_id=26&reportable_type=Comment
    Started POST "/reports" for 127.0.0.1 at 2018-08-24 00:36:13 +0800
    Processing by ReportsController#create as HTML
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"u6iqI2AIxQXf63gmwjHYnJ+QzvDFX+8A0xPlwMtiY4QJcxkSul77gL1d7MnIRbAqU5Qxt4dsha7zZmNV8BNrww==", "report"=>{"reprtable_type"=>"Comment", "reportable_id"=>"26", "radio_content"=>"xxxx", "content"=>""}, "commit"=>"report"}
      User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
      Comment Load (0.3ms)  SELECT  `comments`.* FROM `comments` WHERE (id = NULL) LIMIT 1
    Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.6ms)
    
    NoMethodError - undefined method `commentable_id' for nil:NilClass:
      app/controllers/reports_controller.rb:44:in `get_target'
    
    127.0.0.1 - - [24/Aug/2018:00:36:13 CST] "POST /reports HTTP/1.1" 500 75672
    http://127.0.0.1:3000/questions/15 -> /reports
    Started POST "/__better_errors/4b81417ea02a92e0/variables" for 127.0.0.1 at 2018-08-24 00:36:13 +0800
    127.0.0.1 - - [24/Aug/2018:00:36:13 CST] "POST /__better_errors/4b81417ea02a92e0/variables HTTP/1.1" 200 88217
    http://127.0.0.1:3000/reports -> /__better_errors/4b81417ea02a92e0/variables
    
    

    但是@report_id.to_i输出也确实是 26。

    请问下,是哪里出现错误了呢?非常感谢。@Rei

  • @Rei 非常感谢大佬~~🌹

  • @Rei 谢谢您的回答。我想请问下,reportable_type 和 reportable_id 作为参数传,这个可以举例说明下吗?

    比如在_comments.html.erb中,现在是new_reports_path(@comment) 那么我该怎么在 reports_controller.rb 中,获得@comment的 type 和 id 呢?非常感谢。

  • @Rei @jmmbite @jasl 感谢各位的热心解答,我更新了下问题,增加了_reports.html.erb和详细点的错误提示。

    然后,我在 stackoverflow 上提问后,有人建议说修改_reports.html.erb中的

    <%= form_for [@reportable,@report] do |f| %> 为:<%= form_for [@question,@reportable,@report] do |f| %>

    这个是可以正确提交 reports 并获得@reportable的 type 和 id。

    但是我想把_reports.html.erb作为通用的模板,继续使用<%= form_for [@reportable,@report] do |f| %>,并可以用在 questions、articles 等等模型中。那么我该怎么在reports_controller.rb中设置@reportable,可以获取正确的值?

    如果有说的不清楚的地方,烦请指出。再次感谢热心帮助的大伙。

  • @jonnoj 谢谢你的回答,这个方法试过了呢,但是用:

    def star
       current_user.star_question(params[:id])
      @question.save(touch: false)
    
       # 或者 @question.stars_count.save(touch: false)
       render plain: "1"
     end
    

    这都没效果呢。

    补充:收藏功能是 ajax 实现的:(参考 homeland 里面的)

    $(function () {
        var s = $(".ques-head-footer a.bookmark");
        s.on("click",function (e) {
            e.preventDefault();
            var target_id = s.data("id"),
                target_c = $("span.stars_counts",s) ,
                target_n = target_c.text();
            if (s.hasClass("like")) {
                $.ajax({
                    url: "/questions/" + target_id  + "/unstar",
                    type: "DELETE",
                });
                s.attr("title", "收藏").removeClass("like");
                $("span.target_name",s).html("收藏");
                target_c.text(parseInt(target_n) - 1);
            }
            else{
                $.post ({
                    url: "/questions/" + target_id + "/star",
                });
                s.attr("title","已收藏").addClass("like");
                $("span.target_name",s).html("已收藏");
                target_c.text(parseInt(target_n) + 1);
            }
        });
    });
    
  • @Rei 感谢您的指导。是的,Img 模型是没有用的,这个只是我用来试验的,主要这个还是用到 markdown 里上传图片的。然后,ActiveStorage 确实很好用,但是返回的 url 我不会自定义,返回的 ulr 太长了,所以我就用 carrierwave 了。再次非常感谢您的指导,这个问题困扰了好几天。

  • @Rei 非常感谢您的指导,但是我还是有些地方不是很明白,我更新了下问题,可以请您帮我看下,该怎么修改吗?~~

  • 哦哦,好的。我来试下,谢谢。

  • @a-wing 谢谢你,然后 ActiveStorage 可以用裁剪图片吗?我用 carrierwave 就是可以结合 jcrop,在上传图片完成后,可以裁剪图片并再次覆盖上传。

  • @liukun_lk 请问下我该怎么修改代码呢?如果是用这样的方法:

    <script>
      $(function () {
          $("#user_avatar").on("change",function () {
              $("#upload-modal").modal("show");
          })
      })
    </script>
    

    这个 modal 窗口会一闪而过,就是先执行 js 代码,然后再通过 user_controller.erb 中跳转页面

    非常感谢~

  • @liukun_lk 谢谢你的关注,但是怎么打开 modal 呢?我后来看了别人的代码,做了修改。如下:

    def update
        @user = User.find(params[:id])
        if @user.update_attributes(user_params)
          if params[:user][:picture].present?
            respond_to do |format|
              format.html do
                flash[:warning] = "Template missing"
                redirect_to @user
              end
              format.js { render template: 'users/update.js.erb'}
            end
          else
            redirect_to @user
            flash[:success] = "更新成功"
          end
        else
          render :edit
        end
      end
    

    update.js.erb 内容为:

    $('#uploadModalContent').html("<%= j render "users/modal"%>");
    $('#upload-modal').modal('show');
    

    show.html.erb 内容为:

    <%= form_for @user, :html => {:multipart => true} do |f| %>
      <div class="row " id="user_avatar_crop">
        <!-- 图片选择-->
        <div class="col-md-12">
          <%= f.file_field :picture, id: :user_avatar, onchange: 'this.form.submit()'%>
        </div>
      </div>
    <% end %>
    
    <!-- Modal -->
    <div id="uploadModalContent">
    
    </div>
    
    <!-- 展示用户更新后的图片 -->
    <% if @user.picture? %>
      <%= image_tag @user.picture.url(:thumb), :alt => @user.name+"_avatar" %>
      <% else %>
      <%= image_tag @user.picture.url(:thumb),:alt => @user.name+"_default" %>
      <% end %>
    

    但是不能加载 format.js { render template: 'users/update.js.erb'},后来看了另一个例子,说是如果跳转到 bootstrap modal,需要在链接上加 data-remote="true",如:

    <%= link_to "Edit", edit_user_path(@user), remote: true, class: "btn btn-info" %>
    

    这样是可以打开 modal 的。但是我的需求是在图片上传完成后,即 onchange: 'this.form.submit()' 完成后,再跳到 modal 进行裁剪,那么该怎么添加跳转语句呢?非常感谢~