Skip to content

Commit

Permalink
story: check for duplicate URL on blur
Browse files Browse the repository at this point in the history
  • Loading branch information
talklittle authored and mtnygard committed Jan 30, 2018
1 parent 6ea6b1b commit 5064cfe
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 38 deletions.
12 changes: 12 additions & 0 deletions app/assets/javascripts/application.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ var _Lobsters = Class.extend({
});
},

checkStoryDuplicate: function(form) {
var params = $(form).serializeArray();
$.post("/stories/check_url_dupe", params, function(data) {
var da = $.parseHTML(data);
$(form).find(".form_errors_header").replaceWith(da);
});
},

runSelect2: function() {
$("#story_tags_a").select2({
formatSelection: function(what) {
Expand Down Expand Up @@ -492,6 +500,10 @@ $(document).ready(function() {
ta.addSelectedChoice({ id: tag });
}
}

if ($("#story_url").val().length > 0) {
Lobsters.checkStoryDuplicate($(this).parents("form").first());
}
});

$(document).on("blur", "#story_title", function() {
Expand Down
16 changes: 16 additions & 0 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,22 @@ def unsave
render :plain => "ok"
end

def check_url_dupe
@story = Story.new(story_params)

if @story.url.present?
@story.check_url

# ignore other types of errors (e.g., invalid URL format)
if @story.already_posted_story.blank?
@story.errors.clear
end
end

return render :partial => "stories/formerrors", :layout => false,
:content_type => "text/html", :locals => { :story => @story }
end

private

def story_params
Expand Down
30 changes: 17 additions & 13 deletions app/models/story.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,7 @@ class Story < ActiveRecord::Base

validate do
if self.url.present?
# URI.parse is not very lenient, so we can't use it

if self.url.match(/\Ahttps?:\/\/([^\.]+\.)+[a-z]+(\/|\z)/i)
if self.new_record? && (s = Story.find_similar_by_url(self.url))
self.already_posted_story = s
if s.is_recent?
errors.add(:url, "has already been submitted within the past " <<
"#{RECENT_DAYS} days")
end
end
else
errors.add(:url, "is not valid")
end
check_url
elsif self.description.to_s.strip == ""
errors.add(:description, "must contain text if no URL posted")
end
Expand All @@ -89,6 +77,22 @@ class Story < ActiveRecord::Base
check_tags
end

def check_url
# URI.parse is not very lenient, so we can't use it

if self.url.match(/\Ahttps?:\/\/([^\.]+\.)+[a-z]+(\/|\z)/i)
if self.new_record? && (s = Story.find_similar_by_url(self.url))
self.already_posted_story = s
if s.is_recent?
errors.add(:url, "has already been submitted within the past " <<
"#{RECENT_DAYS} days")
end
end
else
errors.add(:url, "is not valid")
end
end

def self.find_similar_by_url(url)
urls = [ url.to_s ]
urls2 = [ url.to_s ]
Expand Down
27 changes: 2 additions & 25 deletions app/views/stories/_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
<% if f.object.errors.count == 1 && f.object.already_posted_story %>
<div class="flash-error">
<h2>Error: This story was already submitted <%=
time_ago_in_words_label(f.object.already_posted_story.created_at) %></h2>
<p>
Please view the <a href="<%= f.object.already_posted_story.comments_path %>"
target="_blank">previous discussion</a> for this story.
</p>
</div>
<% elsif f.object.errors.any? %>
<%= error_messages_for f.object %>
<% elsif !f.object.errors.any? && f.object.already_posted_story %>
<div class="flash-notice">
<h2>Note: This story was already submitted <%=
time_ago_in_words_label(f.object.already_posted_story.created_at) %>, but
may be submitted again.</h2>
<p>
Please view the <a href="<%= f.object.already_posted_story.comments_path %>"
target="_blank">previous discussion</a> for this story first. If the content
has changed or warrants new discussion, you may submit it again.
</p>
</div>

<%= f.hidden_field :seen_previous %>
<% end %>
<%= render :partial => "stories/formerrors", :locals => {
:story => f.object } %>

<div class="box">
<% unless defined?(suggesting) %>
Expand Down
29 changes: 29 additions & 0 deletions app/views/stories/_formerrors.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<div class="form_errors_header">
<% if story.errors.count == 1 && story.already_posted_story %>
<div class="flash-error">
<h2>Error: This story was already submitted <%=
time_ago_in_words_label(story.already_posted_story.created_at) %></h2>
<p>
Please view the <a href="<%= story.already_posted_story.comments_path %>"
target="_blank">previous discussion</a> for this story.
</p>
</div>
<% elsif story.errors.any? %>
<%= error_messages_for story %>
<% elsif !story.errors.any? && story.already_posted_story %>
<div class="flash-notice">
<h2>Note: This story was already submitted <%=
time_ago_in_words_label(story.already_posted_story.created_at) %>, but
may be submitted again.</h2>
<p>
Please view the <a href="<%= story.already_posted_story.comments_path %>"
target="_blank">previous discussion</a> for this story first. If the content
has changed or warrants new discussion, you may submit it again.
</p>
</div>

<% if defined?(f) %>
<%= f.hidden_field :seen_previous %>
<% end %>
<% end %>
</div>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
end
post "/stories/fetch_url_attributes", :format => "json"
post "/stories/preview" => "stories#preview"
post "/stories/check_url_dupe" => "stories#check_url_dupe"

resources :comments do
member do
Expand Down

0 comments on commit 5064cfe

Please sign in to comment.