Skip to content

Commit

Permalink
Create CommunityLinks.
Browse files Browse the repository at this point in the history
Links must be https.  Add validate_url ruby gem to validate the urls.

Add not null on link site and url.

Add relevant FK.
  • Loading branch information
openbrian committed Aug 8, 2024
1 parent d407e34 commit c5f7dca
Show file tree
Hide file tree
Showing 19 changed files with 467 additions and 8 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ gem "rails_param"
gem "rinku", ">= 2.0.6", :require => "rails_rinku"
gem "strong_migrations", "< 2.0.0"
gem "validates_email_format_of", ">= 1.5.1"
gem "validate_url"

# Native OSM extensions
gem "quad_tile", "~> 1.0.1"
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,9 @@ GEM
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
uri (0.13.0)
validate_url (1.0.15)
activemodel (>= 3.0.0)
public_suffix
validates_email_format_of (1.8.2)
i18n (>= 0.8.0)
simpleidn
Expand Down Expand Up @@ -703,6 +706,7 @@ DEPENDENCIES
terser
turbo-rails
unicode-display_width
validate_url
validates_email_format_of (>= 1.5.1)
vendorer
webmock
Expand Down
2 changes: 2 additions & 0 deletions app/abilities/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def initialize(user)
can [:index, :feed, :show], Changeset
can :index, ChangesetComment
can [:index, :show], Community
can [:index], CommunityLink
can [:confirm, :confirm_resend, :confirm_email], :confirmation
can [:index, :rss, :show], DiaryEntry
can :index, DiaryComment
Expand Down Expand Up @@ -50,6 +51,7 @@ def initialize(user)
can [:new, :create, :reply, :show, :inbox, :outbox, :muted, :mark, :unmute, :destroy], Message
can [:create, :new], Community
can [:edit, :update], Community, { :organizer_id => user.id }
can [:edit, :create, :destroy, :new, :update], CommunityLink, { :community => { :organizer_id => user.id } }
can [:close, :reopen], Note
can [:show, :edit, :update], :preference
can [:edit, :update], :profile
Expand Down
6 changes: 0 additions & 6 deletions app/assets/stylesheets/communities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,4 @@
label {
font-weight: bold;
}
ul {
display: inline-block;
}
ul > li {
display: inline-block;
}
}
61 changes: 61 additions & 0 deletions app/controllers/community_links_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class CommunityLinksController < ApplicationController
layout "site"
before_action :authorize_web

before_action :set_link, :only => [:destroy, :edit, :update]

load_and_authorize_resource :except => [:create, :new]
authorize_resource

def index
@community = Community.friendly.find(params[:community_id])
@links = @community.community_links
end

def new
return "missing parameter community_id" unless params.key?(:community_id)

@community = Community.friendly.find(params[:community_id])
@title = t ".title"
@link = CommunityLink.new
@link.community_id = params[:community_id]
end

def edit; end

def create
@community = Community.friendly.find(params[:community_id])
@link = @community.community_links.build(link_params)
if @link.save
response.set_header("link_id", @link.id) # for testing
redirect_to @link.community, :notice => t(".success")
else
render "new"
end
end

def update
if @link.update(link_params)
redirect_to @link.community, :notice => t(".success")
else
flash.now[:alert] = t(".failure")
render :edit
end
end

def destroy
community_id = @link.community_id
@link.delete
redirect_to community_path(community_id)
end

private

def set_link
@link = CommunityLink.find(params[:id])
end

def link_params
params.require(:community_link).permit(:community_id, :text, :url)
end
end
1 change: 1 addition & 0 deletions app/models/community.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Community < ApplicationRecord
friendly_id :name, :use => :slugged

belongs_to :organizer, :class_name => "User"
has_many :community_links

validates :name, :presence => true, :length => 1..255, :characters => true
validates :description, :presence => true, :length => 1..1023, :characters => true
Expand Down
25 changes: 25 additions & 0 deletions app/models/community_link.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# == Schema Information
#
# Table name: community_links
#
# id :bigint(8) not null, primary key
# community_id :bigint(8) not null
# text :string not null
# url :string not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_community_links_on_community_id (community_id)
#
# Foreign Keys
#
# fk_rails_... (community_id => communities.id)
#

class CommunityLink < ApplicationRecord
belongs_to :community
validates :text, :presence => true, :length => 1..255, :characters => true
validates :url, :presence => true, :length => 1..255, :url => { :schemes => ["https"] }
end
16 changes: 16 additions & 0 deletions app/views/communities/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@
<p>
<%= auto_link @community.description %>
</p>
<div class="d-flex">
<label>
<% if current_user == @community.organizer %>
<%= link_to t(".links"), community_community_links_path(@community) %>
<% else %>
<%= t(".links") %>
<% end %>
</label>
<ul class="ps-2 breadcrumb">
<% @community.community_links.each do |link| %>
<li class="breadcrumb-item">
<a href="<%= link.url %>"><%= link.text %></a>
</li>
<% end %>
</ul>
</div>
<div>
<label><%= t(".organizer") %></label>
<%= link_to @community.organizer.display_name, user_path(@community.organizer) %>
Expand Down
5 changes: 5 additions & 0 deletions app/views/community_links/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= bootstrap_form_for [@community, @link] do |form| %>
<%= form.text_field :text %>
<%= form.text_field :url %>
<%= form.primary %>
<% end %>
3 changes: 3 additions & 0 deletions app/views/community_links/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1><%= t(".edit_community_link") %></h1>

<%= render "form", :link => @link %>
32 changes: 32 additions & 0 deletions app/views/community_links/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<% content_for :heading do %>
<h1><%= t(".title") %></h1>
<nav class="secondary-actions">
<ul class='clearfix'>
<li>
<%= link_to new_community_community_link_path(@community), :class => "icon-link" do %>
<%= plus_icon %>
<%= t(".new") %>
<% end %>
</li>
</ul>
</nav>
<% end %>
<% if !@links.empty? %>
<table class="table table-borderless table-striped">
<tbody>
<% @links.each do |link| %>
<tr>
<td>
<% link.url.slice! "https://" %> <%# prevent XSS %>
<%= link_to link.text, "https://#{link.url}" %>
</td>
<td>
<%= link_to t(".edit"), edit_community_link_path(link) %>
<%= link_to t(".delete"), community_link_path(link), :method => :delete %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
5 changes: 5 additions & 0 deletions app/views/community_links/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<% content_for :heading do %>
<h1><%= @title %></h1>
<% end %>
<%= render "form", :link => @link %>
20 changes: 19 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ en:
email_address_not_routable: is not routable
display_name_is_user_n: can't be user_n unless n is your user id
models:
url: "is not a valid secure URL"
user_mute:
attributes:
subject:
Expand Down Expand Up @@ -520,6 +521,22 @@ en:
title_particular: "OpenStreetMap changeset #%{changeset_id} discussion"
timeout:
sorry: "Sorry, the list of changeset comments you requested took too long to retrieve."
community_links:
create:
success: "Community Link was successfully created."
edit:
edit_community_link: "Edit Community Link"
index:
delete: "Delete"
edit: "Edit"
new: "New"
title: "Community Links"
new:
all: "All"
title: "New Community Link"
update:
failure: "The community link could not be updated."
success: "The community link was successfully updated."
communities:
create:
success: "Community was successfully created."
Expand All @@ -528,7 +545,6 @@ en:
index:
all: "All Communities"
communities_organized: "Communities Organized"
longitude: "Longitude"
new: "New"
new_title: "Create a new community"
sorted_by: "Sorted by name"
Expand All @@ -540,7 +556,9 @@ en:
heading: "No community with the id: %{id}"
body: "Sorry, there is no community with the id %{id}. Please check your spelling, or maybe the link you clicked is wrong."
show:
edit: "Edit"
header_title: "Community"
links: "Links"
organizer: "Organizer"
recent_changes: "Recent Changes"
report: "Report"
Expand Down
5 changes: 4 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,10 @@
resources :redactions

# communities
resources :communities
resources :communities do
resources :community_links, :only => [:create, :index, :new]
end
resources :community_links, :only => [:destroy, :edit, :update]

# errors
match "/400", :to => "errors#bad_request", :via => :all
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20240525143545_create_community_links.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateCommunityLinks < ActiveRecord::Migration[7.0]
def change
create_table :community_links do |t|
t.references :community, :null => false, :foreign_key => true, :index => true
t.string :text, :null => false
t.string :url, :null => false

t.timestamps
end
end
end
64 changes: 64 additions & 0 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,39 @@ CREATE SEQUENCE public.communities_id_seq
ALTER SEQUENCE public.communities_id_seq OWNED BY public.communities.id;


--
-- Name: community_links; Type: TABLE; Schema: public; Owner: -
--

CREATE TABLE public.community_links (
id bigint NOT NULL,
community_id bigint NOT NULL,
text character varying NOT NULL,
url character varying NOT NULL,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);


--
-- Name: community_links_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--

CREATE SEQUENCE public.community_links_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


--
-- Name: community_links_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--

ALTER SEQUENCE public.community_links_id_seq OWNED BY public.community_links.id;


--
-- Name: current_node_tags; Type: TABLE; Schema: public; Owner: -
--
Expand Down Expand Up @@ -1815,6 +1848,13 @@ ALTER TABLE ONLY public.client_applications ALTER COLUMN id SET DEFAULT nextval(
ALTER TABLE ONLY public.communities ALTER COLUMN id SET DEFAULT nextval('public.communities_id_seq'::regclass);


--
-- Name: community_links id; Type: DEFAULT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.community_links ALTER COLUMN id SET DEFAULT nextval('public.community_links_id_seq'::regclass);


--
-- Name: current_nodes id; Type: DEFAULT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -2084,6 +2124,14 @@ ALTER TABLE ONLY public.communities
ADD CONSTRAINT communities_pkey PRIMARY KEY (id);


--
-- Name: community_links community_links_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.community_links
ADD CONSTRAINT community_links_pkey PRIMARY KEY (id);


--
-- Name: current_node_tags current_node_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -2716,6 +2764,13 @@ CREATE INDEX index_communities_on_organizer_id ON public.communities USING btree
CREATE UNIQUE INDEX index_communities_on_slug ON public.communities USING btree (slug);


--
-- Name: index_community_links_on_community_id; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX index_community_links_on_community_id ON public.community_links USING btree (community_id);


--
-- Name: index_diary_entry_subscriptions_on_diary_entry_id; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -3386,6 +3441,14 @@ ALTER TABLE ONLY public.oauth_access_tokens
ADD CONSTRAINT fk_rails_ee63f25419 FOREIGN KEY (resource_owner_id) REFERENCES public.users(id) NOT VALID;


--
-- Name: community_links fk_rails_f60a749c39; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.community_links
ADD CONSTRAINT fk_rails_f60a749c39 FOREIGN KEY (community_id) REFERENCES public.communities(id);


--
-- Name: friends friends_friend_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
Expand Down Expand Up @@ -3727,6 +3790,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('21'),
('20240618193051'),
('20240605134916'),
('20240525143545'),
('20240525030520'),
('20240525020545'),
('20240405083825'),
Expand Down
Loading

0 comments on commit c5f7dca

Please sign in to comment.