如果新帖子与应用中的现有帖子具有某种共性,如何使用参数来限制新帖子

时间:2018-01-06 09:58:48

标签: ruby-on-rails

如果新用户帖子中80%的单词与其他用户(包括当前用户)创建的帖子相似,如何设置禁止用户发布新帖子的限制。(我有一个当前用户) char.limit每个帖子100个),

在“观看次数”中,只有当任何其他帖子中的字词与80%或更少的字词相同时,才会发布帖子。

作为例如,如果用户发布“预测明天天气晴朗”。

然而,如果一个帖子“明天天气预报会是阴天”已经存在。 由于新帖子中80%的单词与现有帖子中的单词相同,因此不允许使用新帖子。

到目前为止,我有:

Posts.controller.rb

class PostsController < ApplicationController


    def new 
        @post = Post.new
    end

    def create
        @post = Post.new(post_params)
        @post.user_id = current_user.id 
        respond_to do |f|
            if (@post.save) 
                f.html { redirect_to "", notice: "Post created!" }
            else
                f.html { redirect_to "", notice: "Error: Post Not Saved." }
            end
        end
    end


    private
    def post_params 
        params.require(:post).permit(:user_id, :content)         
    end

end

_post_form.html.erb

<% if user_signed_in? %>
  <div class="panel panel-default post-form-panel">
    <div class="panel-body row">


     <div class="col-sm-11">
        <%= form_for(@newPost)  do |f| %> 
              <div class="field" style="margin-left: 10px;">
                <%= f.text_field :content, autofocus: true, class: "form-control" %>
                <span type="button" class="btn btn-submit" style="float: right; margin-top: 3px;"><%= f.submit "Add Post", class: "btn btn-primary" %></span>
              </div>
        <% end %>
      </div>
    </div>
  </div>
<% end %>

Post.rb

class Post < ActiveRecord::Base
  belongs_to :user
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 100} # posts are capped at 100 chars.
  default_scope -> { order(created_at: :desc) } # newest posts first
end

各种观点 - 主页,个人资料等

1 个答案:

答案 0 :(得分:0)

首先,个人建议。不要使用default_scope(这里有一篇关于原因的好文章:https://rails-bestpractices.com/posts/2013/06/15/default_scope-is-evil/)。

TL / DR :如果您想按照ID的顺序提取评论,则必须Post.unscoped.order(:id)

回到你的问题。如果有相似的帖子,你想要的可能是帖子无效。这是一个粗略的方法:

<强> Post.rb

class Post < ActiveRecord::Base
  belongs_to :user
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 100} # posts are capped at 100 chars.
  validates :post_is_unique

  private

  def post_is_unique
    # Select all posts where the id does not match current id and fetch the contents
    other_post_contents = self.class.where.not(id: id).pluck(:content)
    # Split each content by space (**NOTE:** Other data cleaning may be needed -- remove non-alphanumeric characters)
    other_post_contents = other_post_contents.map{ |c| c.split(" ").uniq }
    # Now we need to compare the current content with all the other contents and see if they match
    current_content = content.split(" ").uniq
    other_post_contents.each do |other_content|
      # words in common
      common_words = other_content & current_content
      # If the ratio of common words exceeds 0.8 (80%)
      if (common_words.length / other_content.length) > 0.8
        # Add an error and exit early
        errors.add(:base, "current post is too similar to another post")
        return false
      end
    end
  end
end

我想强调一点,这更像是一个绑定解决方案。随着帖子数量的增加,它将不得不搜索更多帖子以查看新帖子是否有效。我建议您将此验证步骤移至后台作业