diff --git a/app.json b/app.json new file mode 100644 index 00000000..97bc07a7 --- /dev/null +++ b/app.json @@ -0,0 +1,65 @@ +{ + "name": "notebook", + "scripts": { + }, + "env": { + "AWS_ACCESS_KEY_ID": { + "required": true + }, + "AWS_REGION": { + "required": true + }, + "AWS_SECRET_ACCESS_KEY": { + "required": true + }, + "GOOGLE_TRANSLATE_API_KEY": { + "required": true + }, + "HEROKU_POSTGRESQL_BROWN_URL": { + "required": true + }, + "LANG": { + "required": true + }, + "LOG_LEVEL": { + "required": true + }, + "RACK_ENV": { + "required": true + }, + "RAILS_ENV": { + "required": true + }, + "RAILS_SERVE_STATIC_FILES": { + "required": true + }, + "RUBY_GC_HEAP_GROWTH_FACTOR": { + "required": true + }, + "S3_BUCKET_NAME": { + "required": true + }, + "SECRET_KEY_BASE": { + "required": true + }, + "SECRET_TOKEN": { + "required": true + }, + "STRIPE_API_KEY": { + "required": true + }, + "STRIPE_PUBLISHABLE_KEY": { + "required": true + } + }, + "formation": { + }, + "addons": [ + "heroku-postgresql" + ], + "buildpacks": [ + { + "url": "heroku/ruby" + } + ] +} diff --git a/app/assets/images/card-headers/floras.jpg b/app/assets/images/card-headers/floras.jpg new file mode 100644 index 00000000..834bcfe9 Binary files /dev/null and b/app/assets/images/card-headers/floras.jpg differ diff --git a/app/assets/javascripts/floras.coffee b/app/assets/javascripts/floras.coffee new file mode 100644 index 00000000..24f83d18 --- /dev/null +++ b/app/assets/javascripts/floras.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/floras.scss b/app/assets/stylesheets/floras.scss new file mode 100644 index 00000000..18b2d428 --- /dev/null +++ b/app/assets/stylesheets/floras.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Floras controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/content_controller.rb b/app/controllers/content_controller.rb index c4bbacef..e4c22707 100644 --- a/app/controllers/content_controller.rb +++ b/app/controllers/content_controller.rb @@ -33,13 +33,13 @@ class ContentController < ApplicationController 'content_type': content_type.name, 'content_owner': current_user.present? && current_user.id == @content.user_id, 'logged_in_user': current_user.present? - }) + }) if Rails.env.production? else Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed recently-modified content', { 'content_type': content_type.name, 'content_owner': current_user.present? && current_user.id == @content.user_id, 'logged_in_user': current_user.present? - }) + }) if Rails.env.production? end end @@ -94,7 +94,7 @@ class ContentController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'created content', { 'content_type': content_type.name - }) + }) if Rails.env.production? if @content.save if params.key? 'image_uploads' @@ -117,7 +117,7 @@ class ContentController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'updated content', { 'content_type': content_type.name - }) + }) if Rails.env.production? if params.key? 'image_uploads' upload_files params['image_uploads'], content_type.name, @content.id @@ -156,7 +156,7 @@ class ContentController < ApplicationController 'content_type': content_type, 'image_size_kb': image_size_kb, 'first five images': current_user.image_uploads.count <= 5 - }) + }) if Rails.env.production? end end @@ -170,7 +170,7 @@ class ContentController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'deleted content', { 'content_type': content_type.name - }) + }) if Rails.env.production? @content.destroy diff --git a/app/controllers/export_controller.rb b/app/controllers/export_controller.rb index a641e486..7c44ead2 100644 --- a/app/controllers/export_controller.rb +++ b/app/controllers/export_controller.rb @@ -4,14 +4,14 @@ class ExportController < ApplicationController def index Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed export page', { 'content count': current_user.content_count - }) + }) if Rails.env.production? end def report_to_mixpanel format, scope Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'exported content', { 'export format': format, 'scope': scope - }) + }) if Rails.env.production? end # Formats diff --git a/app/controllers/floras_controller.rb b/app/controllers/floras_controller.rb new file mode 100644 index 00000000..243c9a00 --- /dev/null +++ b/app/controllers/floras_controller.rb @@ -0,0 +1,25 @@ +class FlorasController < ContentController + private + + def content_params + params.require(:flora).permit(content_param_list) + end + + def content_param_list + %i( + name description aliases universe_id + order family genus + colorings size smell taste + fruits seeds nuts berries medicinal_purposes + reproduction seasonality + privacy + notes private_notes + ) + [ + custom_attribute_values: [:name, :value], + flora_relationships_attributes: [:id, :related_flora_id, :_destroy], + flora_magical_effects_attributes: [:id, :magic_id, :_destroy], + flora_locations_attributes: [:id, :location_id, :_destroy], + flora_eaten_by_attributes: [:id, :creature_id, :_destroy], + ] + end +end diff --git a/app/controllers/image_upload_controller.rb b/app/controllers/image_upload_controller.rb index 1e6e3c19..f8b6536e 100644 --- a/app/controllers/image_upload_controller.rb +++ b/app/controllers/image_upload_controller.rb @@ -28,7 +28,7 @@ class ImageUploadController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'deleted image', { 'image_size_kb': reclaimed_space_kb - }) + }) if Rails.env.production? render json: { success: result }, status: 200 end diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 91711e43..4a5e1131 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -7,7 +7,7 @@ class SubscriptionsController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed billing page', { 'current billing plan': current_user.selected_billing_plan_id, 'content count': current_user.content_count - }) + }) if Rails.env.production? # We only support a single billing plan right now, so just grab the first one. If they don't have an active plan, # we also treat them as if they have a Starter plan. @@ -163,7 +163,7 @@ class SubscriptionsController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed payment method page', { 'current billing plan': current_user.selected_billing_plan_id, 'content count': current_user.content_count - }) + }) if Rails.env.production? end def information_change @@ -300,7 +300,7 @@ class SubscriptionsController < ApplicationController end def stripe_webhook - Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'stripe webhook') + Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'stripe webhook') if Rails.env.production? #todo handle webhooks end diff --git a/app/controllers/universes_controller.rb b/app/controllers/universes_controller.rb index 31a1f5ea..840a0f6a 100644 --- a/app/controllers/universes_controller.rb +++ b/app/controllers/universes_controller.rb @@ -1,4 +1,19 @@ class UniversesController < ContentController + + # TODO: pull list of content types out from some centralized list somewhere + [ + :characters, :locations, :items, :creatures, :races, :religions, :groups, :magics, :languages, :floras, :scenes + ].each do |content_type_name| + define_method content_type_name do + @content_type = content_type_name.to_s.singularize.capitalize.constantize + + @universe = Universe.find(params[:id]) + @content_list = @universe.send(content_type_name).is_public.order(:name) + + render :content_list + end + end + private def content_params diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e1bcadf2..eb5e4827 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -8,6 +8,6 @@ class UsersController < ApplicationController Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(@user.id, 'viewed profile', { 'sharing any content': @user.public_content_count != 0 - }) + }) if Rails.env.production? end end diff --git a/app/helpers/floras_helper.rb b/app/helpers/floras_helper.rb new file mode 100644 index 00000000..392b6f67 --- /dev/null +++ b/app/helpers/floras_helper.rb @@ -0,0 +1,2 @@ +module FlorasHelper +end diff --git a/app/models/concerns/has_content.rb b/app/models/concerns/has_content.rb index 3c4e1c4e..4f6af358 100644 --- a/app/models/concerns/has_content.rb +++ b/app/models/concerns/has_content.rb @@ -17,6 +17,7 @@ module HasContent has_many :magics has_many :languages has_many :groups + has_many :floras # Collective content types has_many :scenes diff --git a/app/models/content_groupers/flora_eaten_by.rb b/app/models/content_groupers/flora_eaten_by.rb new file mode 100644 index 00000000..793b4ed8 --- /dev/null +++ b/app/models/content_groupers/flora_eaten_by.rb @@ -0,0 +1,8 @@ +class FloraEatenBy < ActiveRecord::Base + include HasContentLinking + + belongs_to :user + + belongs_to :flora + belongs_to :creature +end diff --git a/app/models/content_groupers/flora_location.rb b/app/models/content_groupers/flora_location.rb new file mode 100644 index 00000000..38e581fb --- /dev/null +++ b/app/models/content_groupers/flora_location.rb @@ -0,0 +1,8 @@ +class FloraLocation < ActiveRecord::Base + include HasContentLinking + + belongs_to :user + + belongs_to :flora + belongs_to :location +end diff --git a/app/models/content_groupers/flora_magical_effect.rb b/app/models/content_groupers/flora_magical_effect.rb new file mode 100644 index 00000000..e9e8dbf1 --- /dev/null +++ b/app/models/content_groupers/flora_magical_effect.rb @@ -0,0 +1,8 @@ +class FloraMagicalEffect < ActiveRecord::Base + include HasContentLinking + + belongs_to :user + + belongs_to :flora + belongs_to :magic, class_name: 'Magic' +end diff --git a/app/models/content_groupers/flora_relationship.rb b/app/models/content_groupers/flora_relationship.rb new file mode 100644 index 00000000..e1ef33f7 --- /dev/null +++ b/app/models/content_groupers/flora_relationship.rb @@ -0,0 +1,21 @@ +class FloraRelationship < ActiveRecord::Base + include HasContentLinking + LINK_TYPE = :two_way + + belongs_to :user + + belongs_to :flora + belongs_to :related_flora, class_name: 'Flora' + + after_create do + self.reciprocate relation: :flora_relationships, parent_object_ref: :flora, added_object_ref: :related_flora + end + + after_destroy do + # This is a two-way relation, so we should also delete the reverse association + this_object = Flora.find_by(id: self.flora_id) + other_object = Flora.find_by(id: self.related_flora_id) + + other_object.related_floras.delete this_object + end +end diff --git a/app/models/content_types/flora.rb b/app/models/content_types/flora.rb new file mode 100644 index 00000000..636588f7 --- /dev/null +++ b/app/models/content_types/flora.rb @@ -0,0 +1,38 @@ +class Flora < ActiveRecord::Base + validates :name, presence: true + + belongs_to :user + validates :user_id, presence: true + + include BelongsToUniverse + + include HasAttributes + include HasPrivacy + include HasContentGroupers + include HasImageUploads + include HasChangelog + + include Serendipitous::Concern + + include Authority::Abilities + self.authorizer_name = 'ExtendedContentAuthorizer' + + relates :related_floras, with: :flora_relationships + relates :magics, with: :flora_magical_effects + relates :locations, with: :flora_locations + relates :creatures, with: :flora_eaten_by + + scope :is_public, -> { eager_load(:universe).where('floras.privacy = ? OR universes.privacy = ?', 'public', 'public') } + + def self.content_name + 'flora' + end + + def self.color + 'text-lighten-3 lighten-3 teal' + end + + def self.icon + 'local_florist' + end +end diff --git a/app/models/content_types/universe.rb b/app/models/content_types/universe.rb index 6e22fdfc..a5d40178 100644 --- a/app/models/content_types/universe.rb +++ b/app/models/content_types/universe.rb @@ -31,6 +31,7 @@ class Universe < ActiveRecord::Base has_many :religions has_many :magics has_many :languages + has_many :floras has_many :scenes has_many :groups diff --git a/app/views/content/cards/_in_universe_content_list.html.erb b/app/views/content/cards/_in_universe_content_list.html.erb index e2d1e8e1..b796ca46 100644 --- a/app/views/content/cards/_in_universe_content_list.html.erb +++ b/app/views/content/cards/_in_universe_content_list.html.erb @@ -30,7 +30,11 @@ <%= content_type_class.icon %> <% end %> - <%= content_type.to_s.pluralize.titleize %> + <% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe %> + <%= link_to content_type.to_s.pluralize.titleize, send("#{content_type.to_s.pluralize}_universe_path", { id: @content.id }), class: "#{content_type_class.color}-text" %> + <% else %> + <%= content_type.to_s.pluralize.titleize %> + <% end %> close <% if content_list.any? %> @@ -54,6 +58,16 @@ <% end %> +
+ <% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe %> + <%= link_to "Browse #{content_type.to_s.pluralize}", send("#{content_type.to_s.pluralize}_universe_path", { id: @content.id }), class: "btn #{content_type_class.color} lighten-1" %> + <% else %> +
+ <% button_text = content_list.any? ? "Create another #{content_type}" : "Create one" %> + <%= link_to button_text, new_polymorphic_path(content_type), class: "btn #{content_type_class.color}" if current_user %> +
+ <% end %> +
<% elsif content_list.empty? %>
diff --git a/app/views/content/contexts/_creature.html.erb b/app/views/content/contexts/_creature.html.erb index e69de29b..e498655f 100644 --- a/app/views/content/contexts/_creature.html.erb +++ b/app/views/content/contexts/_creature.html.erb @@ -0,0 +1,38 @@ +<%= + render partial: 'content/contexts/relation', locals: { + content_type: Flora, + content: content, + relation_class: FloraEatenBy, + relation_class_id: :creature_id, + relation_text: :eats + } +%> + +<% @references.each do |content_type, relations| %> + <% next unless relations.any? %> + <% + card_title = if relations.count == 1 + if relations.first.first.include? '' + relations.first.first + else + [ + relations.first.first, + ' ', + pluralize(relations.count, "#{content_type.to_s.singularize}") + ].join + end + else + [ + 'Related to ', + pluralize(relations.count, "other #{content_type.to_s.singularize}") + ].join + end + %> +
+ <%= render partial: 'content/cards/content_relation_list', locals: { + content_type: content_type, + relations: relations, + card_title: card_title + } %> +
+<% end %> diff --git a/app/views/content/contexts/_location.html.erb b/app/views/content/contexts/_location.html.erb index d727cd8f..d213e5c1 100644 --- a/app/views/content/contexts/_location.html.erb +++ b/app/views/content/contexts/_location.html.erb @@ -57,6 +57,16 @@ } %> +<%= + render partial: 'content/contexts/relation', locals: { + content_type: Flora, + content: content, + relation_class: FloraLocation, + relation_class_id: :location_id, + relation_text: ' found here' + } +%> + <% scenes = SceneLocationship.where(scene_location_id: content.id).map(&:scene).compact.select { |content| content && content.readable_by?(current_user || User.new) } %> <% if scenes.any? %>
diff --git a/app/views/content/contexts/_magic.html.erb b/app/views/content/contexts/_magic.html.erb new file mode 100644 index 00000000..cf6382da --- /dev/null +++ b/app/views/content/contexts/_magic.html.erb @@ -0,0 +1,9 @@ +<%= + render partial: 'content/contexts/relation', locals: { + content_type: Flora, + content: content, + relation_class: FloraMagicalEffect, + relation_class_id: :magic_id, + relation_text: 'effect of' + } +%> \ No newline at end of file diff --git a/app/views/content/display/_floating_action_buttons.html.erb b/app/views/content/display/_floating_action_buttons.html.erb index 85bb0de3..230aef2d 100644 --- a/app/views/content/display/_floating_action_buttons.html.erb +++ b/app/views/content/display/_floating_action_buttons.html.erb @@ -44,6 +44,6 @@ style: 'z-index: 500;', method: :delete, data: { confirm: "Are you sure? Deleting this #{@content.class.name.downcase} cannot be undone!" } do %> - delete sip + delete <% end %> <% end %> diff --git a/app/views/content/form/_relation_input.html.erb b/app/views/content/form/_relation_input.html.erb index c6059623..58a99510 100644 --- a/app/views/content/form/_relation_input.html.erb +++ b/app/views/content/form/_relation_input.html.erb @@ -2,7 +2,7 @@
- <%= f.label attribute, I18n.translate( + <%= f.label attribute, I18n.translate( "attributes.#{f.object.class.name.downcase}.#{attribute}", scope: :activerecord, default: attribute.humanize.capitalize diff --git a/app/views/content/show.html.erb b/app/views/content/show.html.erb index acb35781..f205d8ce 100644 --- a/app/views/content/show.html.erb +++ b/app/views/content/show.html.erb @@ -125,6 +125,8 @@ <%= render partial: 'content/contexts/creature', locals: { content: @content } %> <% elsif @content.is_a? Race %> <%= render partial: 'content/contexts/race', locals: { content: @content } %> + <% elsif @content.is_a? Magic %> + <%= render partial: 'content/contexts/magic', locals: { content: @content } %> <% elsif @content.is_a? Language %> <%= render partial: 'content/contexts/language', locals: { content: @content } %> <% end %> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index fb896ab1..c4582218 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -27,7 +27,7 @@ Privacy Policy / Source Code / Twitter / - Facebook + Facebook
diff --git a/app/views/layouts/_sidenav.html.erb b/app/views/layouts/_sidenav.html.erb index fac21d65..340be094 100644 --- a/app/views/layouts/_sidenav.html.erb +++ b/app/views/layouts/_sidenav.html.erb @@ -95,7 +95,7 @@ %> <% - [Creature, Race, Religion, Group, Magic, Language].each do |extended_content_type| + [Creature, Race, Religion, Group, Magic, Language, Flora].each do |extended_content_type| %>
  • <%= link_to polymorphic_path(extended_content_type) do %> diff --git a/app/views/main/dashboard.html.erb b/app/views/main/dashboard.html.erb index 3099a16e..18ad8e36 100644 --- a/app/views/main/dashboard.html.erb +++ b/app/views/main/dashboard.html.erb @@ -26,7 +26,7 @@ %>
    - <% [:universe, :character, :location, :item, :creature, :race, :religion, :group, :magic, :language, :scene].each do |type| %> + <% [:universe, :character, :location, :item, :creature, :race, :religion, :group, :magic, :language, :flora, :scene].each do |type| %> <% content_list = current_user.send(type.to_s.pluralize) %> <% content_list = content_list.in_universe(@universe_scope) if (@universe_scope.present? && type != :universe) %> <% next if !current_user.can_create?(type.to_s.capitalize.constantize) && content_list.empty? %> diff --git a/app/views/universes/content_list.html.erb b/app/views/universes/content_list.html.erb new file mode 100644 index 00000000..7817a820 --- /dev/null +++ b/app/views/universes/content_list.html.erb @@ -0,0 +1,41 @@ +<% if @content_list.any? %> +
    +
    +
    +
    + <%= image_tag "card-headers/#{@content_type.to_s.downcase.pluralize}" %> + + <%= @content_type.icon %> + <%= @content_type.to_s.capitalize.pluralize %> + in + <%= Universe.icon %> + <%= link_to @universe.name, @universe, class: 'light-blue-text' %> + +
    +
    + <%= render partial: 'content/list/list', locals: { content_list: @content_list } %> +
    +
    + <%= link_to "Back to #{@universe.name}", @universe %> +
    +
    +
    +
    +<% else %> +
    +

    + <%= Universe.icon %> + <%= link_to @universe.name, @universe %> + doesn't contain any + <%= @content_type.name.downcase.pluralize %> yet! +

    +

    + + <%= @content_type.icon %> + +

    +

    + <%= t("content_descriptions.#{@content_type.name.downcase}") %> +

    +
    +<% end %> diff --git a/config/attributes/character.yml b/config/attributes/character.yml index 137cdbc8..82c45e78 100644 --- a/config/attributes/character.yml +++ b/config/attributes/character.yml @@ -75,15 +75,15 @@ - :name: occupation :label: Occupation - :name: fave_color - :label: Color + :label: Favorite Color - :name: fave_food - :label: Food + :label: Favorite Food - :name: fave_possession - :label: Possession + :label: Favorite Possession - :name: fave_weapon - :label: Weapon + :label: Favorite Weapon - :name: fave_animal - :label: Animal + :label: Favorite Animal :history: :label: history :icon: info diff --git a/config/attributes/flora.yml b/config/attributes/flora.yml new file mode 100644 index 00000000..916ea8e2 --- /dev/null +++ b/config/attributes/flora.yml @@ -0,0 +1,79 @@ +:overview: + :label: Overview + :icon: info + :attributes: + - :name: name + :label: Name + - :name: description + :label: Description + - :name: aliases + :label: Other names + - :name: universe_id + :label: Universe +:classification: + :label: Classification + :icon: bubble_chart + :attributes: + - :name: order + :label: Order + - :name: family + :label: Family + - :name: genus + :label: Genus + - :name: related_floras + :label: Related flora +:appearance: + :label: Appearance + :icon: local_florist + :attributes: + - :name: colorings + :label: Colorings + - :name: size + :label: Size + - :name: smell + :label: Smell + - :name: taste + :label: Taste +:produce: + :label: Produce + :icon: add_box + :attributes: + - :name: fruits + :label: Fruits + - :name: seeds + :label: Seeds + - :name: nuts + :label: Nuts + - :name: berries + :label: Berries + - :name: medicinal_purposes + :label: Medicinal purposes + - :name: magics + :label: Magical effects +:ecosystem: + :label: ecosystem + :icon: language + :attributes: + - :name: locations + :label: Locations + - :name: reproduction + :label: Reproduction + - :name: seasonality + :label: Seasonality + - :name: creatures + :label: Eaten by +:gallery: + :label: Gallery + :icon: photo_library +:changelog: + :label: Changelog + :icon: history +:notes: + :label: Notes + :icon: edit + :attributes: + - :name: notes + :label: Notes + - :name: private_notes + :label: Private Notes + :description: Private notes are always visible to only you, even if content is made public and shared. diff --git a/config/locales/en.yml b/config/locales/en.yml index 5c3778e7..cb31056c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -155,22 +155,28 @@ en: haircolor: Hair color identmarks: Identifying marks + location: + map: Map + creature: name: Name description: Description type_of: Type of creature other_names: Other names + religion: + practicing_locations: Locations + + flora: + magics: Magical effects + creatures: Eaten by + locations: Locations found + scene: scene_characters: Characters in scene scene_locations: Locations in scene scene_items: Items in scene - religion: - practicing_locations: Locations - - location: - map: Map serendipitous_questions: attributes: universe: @@ -366,6 +372,25 @@ en: #numbers: #quantifiers: + flora: + name: What's the name of this flora? + description: How would you describe %{name}? + aliases: What other names is %{name} known by? + + colorings: What kinds of colorings are found on %{name}? + size: How big does %{name} grow? + smell: What does %{name} smell like? + taste: What does %{name} taste like? + + fruits: What fruits does %{name} produce? + seeds: What kinds of seeds does %{name} produce? + nuts: What kinds of nuts does %{name} produce? + berries: What kinds of berries does %{name} produce? + medicinal_purposes: Does %{name} have any medicinal use? + + reproduction: How does %{name} reproduce and spread? + seasonality: What seasons or climates is %{name} most often found in? + blacklist: _: @@ -389,6 +414,7 @@ en: group: From fellowships to organizations magic: Spells, potions, and other magical things language: Design your own languages + flora: The plants and nature of your world scene: Create scenes to organize a plot content_descriptions: @@ -417,6 +443,8 @@ en: Often a source of magic creates a multitude of spells, potions, and occasional trinkets. language: > Language is the bond that weaves a culture's words together. Are there any new languages in your world? + flora: > + The plants, flowers, trees, and other nature in your world. Paint your landscape with rich flora. scene: > Scenes are events that happen in your world, ranging in size from a nice breakfast to entire wars. attributefield: > diff --git a/config/routes.rb b/config/routes.rb index 414dbbd8..41a14769 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -75,7 +75,19 @@ Rails.application.routes.draw do # Planning scope '/plan' do # Core content types - resources :universes + resources :universes do + get :characters, on: :member + get :locations, on: :member + get :items, on: :member + get :creatures, on: :member + get :races, on: :member + get :religions, on: :member + get :magics, on: :member + get :languages, on: :member + get :floras, on: :member + get :scenes, on: :member + get :groups, on: :member + end resources :characters do get :autocomplete_character_name, on: :collection, as: :autocomplete_name end @@ -90,6 +102,7 @@ Rails.application.routes.draw do resources :religions resources :magics resources :languages + resources :floras # Content usage resources :scenes diff --git a/db/migrate/20170731000013_create_floras.rb b/db/migrate/20170731000013_create_floras.rb new file mode 100644 index 00000000..78e4716b --- /dev/null +++ b/db/migrate/20170731000013_create_floras.rb @@ -0,0 +1,25 @@ +class CreateFloras < ActiveRecord::Migration + def change + create_table :floras do |t| + t.string :name + t.string :description + t.string :aliases + t.string :order + t.string :family + t.string :genus + t.string :colorings + t.string :size + t.string :smell + t.string :taste + t.string :fruits + t.string :seeds + t.string :nuts + t.string :berries + t.string :medicinal_purposes + t.string :reproduction + t.string :seasonality + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20170731000608_add_user_to_flora.rb b/db/migrate/20170731000608_add_user_to_flora.rb new file mode 100644 index 00000000..ff424139 --- /dev/null +++ b/db/migrate/20170731000608_add_user_to_flora.rb @@ -0,0 +1,5 @@ +class AddUserToFlora < ActiveRecord::Migration + def change + add_reference :floras, :user, index: true, foreign_key: true + end +end diff --git a/db/migrate/20170731001131_add_universe_to_flora.rb b/db/migrate/20170731001131_add_universe_to_flora.rb new file mode 100644 index 00000000..885d1b25 --- /dev/null +++ b/db/migrate/20170731001131_add_universe_to_flora.rb @@ -0,0 +1,5 @@ +class AddUniverseToFlora < ActiveRecord::Migration + def change + add_reference :floras, :universe, index: true, foreign_key: true + end +end diff --git a/db/migrate/20170731001803_add_notes_to_flora.rb b/db/migrate/20170731001803_add_notes_to_flora.rb new file mode 100644 index 00000000..8bc7bcb2 --- /dev/null +++ b/db/migrate/20170731001803_add_notes_to_flora.rb @@ -0,0 +1,6 @@ +class AddNotesToFlora < ActiveRecord::Migration + def change + add_column :floras, :notes, :string + add_column :floras, :private_notes, :string + end +end diff --git a/db/migrate/20170731004406_create_flora_magical_effects.rb b/db/migrate/20170731004406_create_flora_magical_effects.rb new file mode 100644 index 00000000..d76b201e --- /dev/null +++ b/db/migrate/20170731004406_create_flora_magical_effects.rb @@ -0,0 +1,10 @@ +class CreateFloraMagicalEffects < ActiveRecord::Migration + def change + create_table :flora_magical_effects do |t| + t.integer :flora_id + t.integer :magic_id + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20170731004450_create_flora_locations.rb b/db/migrate/20170731004450_create_flora_locations.rb new file mode 100644 index 00000000..d7f9d5ba --- /dev/null +++ b/db/migrate/20170731004450_create_flora_locations.rb @@ -0,0 +1,10 @@ +class CreateFloraLocations < ActiveRecord::Migration + def change + create_table :flora_locations do |t| + t.integer :flora_id + t.integer :location_id + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20170731004509_create_flora_eaten_bies.rb b/db/migrate/20170731004509_create_flora_eaten_bies.rb new file mode 100644 index 00000000..c96a65fa --- /dev/null +++ b/db/migrate/20170731004509_create_flora_eaten_bies.rb @@ -0,0 +1,10 @@ +class CreateFloraEatenBies < ActiveRecord::Migration + def change + create_table :flora_eaten_bies do |t| + t.integer :flora_id + t.integer :creature_id + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20170731004712_create_flora_relationships.rb b/db/migrate/20170731004712_create_flora_relationships.rb new file mode 100644 index 00000000..055b6755 --- /dev/null +++ b/db/migrate/20170731004712_create_flora_relationships.rb @@ -0,0 +1,10 @@ +class CreateFloraRelationships < ActiveRecord::Migration + def change + create_table :flora_relationships do |t| + t.integer :flora_id + t.integer :related_flora_id + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20170731010449_add_privacy_to_flora.rb b/db/migrate/20170731010449_add_privacy_to_flora.rb new file mode 100644 index 00000000..e9569610 --- /dev/null +++ b/db/migrate/20170731010449_add_privacy_to_flora.rb @@ -0,0 +1,5 @@ +class AddPrivacyToFlora < ActiveRecord::Migration + def change + add_column :floras, :privacy, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index ed166313..8df178bf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170724114833) do +ActiveRecord::Schema.define(version: 20170731010449) do create_table "archenemyships", force: :cascade do |t| t.integer "user_id" @@ -246,6 +246,64 @@ ActiveRecord::Schema.define(version: 20170724114833) do t.datetime "updated_at", null: false end + create_table "flora_eaten_bies", force: :cascade do |t| + t.integer "flora_id" + t.integer "creature_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "flora_locations", force: :cascade do |t| + t.integer "flora_id" + t.integer "location_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "flora_magical_effects", force: :cascade do |t| + t.integer "flora_id" + t.integer "magic_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "flora_relationships", force: :cascade do |t| + t.integer "flora_id" + t.integer "related_flora_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "floras", force: :cascade do |t| + t.string "name" + t.string "description" + t.string "aliases" + t.string "order" + t.string "family" + t.string "genus" + t.string "colorings" + t.string "size" + t.string "smell" + t.string "taste" + t.string "fruits" + t.string "seeds" + t.string "nuts" + t.string "berries" + t.string "medicinal_purposes" + t.string "reproduction" + t.string "seasonality" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "user_id" + t.integer "universe_id" + t.string "notes" + t.string "private_notes" + t.string "privacy" + end + + add_index "floras", ["universe_id"], name: "index_floras_on_universe_id" + add_index "floras", ["user_id"], name: "index_floras_on_user_id" + create_table "friendly_id_slugs", force: :cascade do |t| t.string "slug", null: false t.integer "sluggable_id", null: false @@ -603,6 +661,13 @@ ActiveRecord::Schema.define(version: 20170724114833) do t.datetime "updated_at", null: false end + create_table "related_floras", force: :cascade do |t| + t.integer "flora_id" + t.integer "related_flora_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "religions", force: :cascade do |t| t.string "name" t.string "description" diff --git a/features/serendipitous_cards.feature b/features/serendipitous_cards.feature index ef67a78d..2459ce0d 100644 --- a/features/serendipitous_cards.feature +++ b/features/serendipitous_cards.feature @@ -3,6 +3,7 @@ Feature: Serendipitous cards Scenario: I update character info using a serendipitous card Given I am logged-in And I create a character - When I view that character + When I view the dashboard + Then I should see my dashboard And I answer the Serendipitous question Then that new field should be saved diff --git a/features/step_definitions/steps.rb b/features/step_definitions/steps.rb index 188b4346..c5691ad9 100644 --- a/features/step_definitions/steps.rb +++ b/features/step_definitions/steps.rb @@ -31,6 +31,10 @@ When 'I log out' do visit destroy_user_session_path end +When(/^I view the dashboard/) do + visit dashboard_path +end + Then 'I should see my dashboard' do expect(current_path).to eq(dashboard_path) end @@ -52,9 +56,9 @@ end When(/^I change my (character|location|item|universe)\'s name$/) do |model| visit polymorphic_path(@model) - click_on "Edit this #{model}" + click_on 'edit' fill_in "#{model}_name", with: 'My changed name' - click_on "Update" + click_on 'save' @model.reload end diff --git a/test/controllers/floras_controller_test.rb b/test/controllers/floras_controller_test.rb new file mode 100644 index 00000000..6cec4bff --- /dev/null +++ b/test/controllers/floras_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FlorasControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/flora_eaten_bies.yml b/test/fixtures/flora_eaten_bies.yml new file mode 100644 index 00000000..0af5dbb5 --- /dev/null +++ b/test/fixtures/flora_eaten_bies.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + flora_id: 1 + creature_id: 1 + +two: + flora_id: 1 + creature_id: 1 diff --git a/test/fixtures/flora_locations.yml b/test/fixtures/flora_locations.yml new file mode 100644 index 00000000..7ea56c96 --- /dev/null +++ b/test/fixtures/flora_locations.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + flora_id: 1 + location_id: 1 + +two: + flora_id: 1 + location_id: 1 diff --git a/test/fixtures/flora_magical_effects.yml b/test/fixtures/flora_magical_effects.yml new file mode 100644 index 00000000..ee97d1eb --- /dev/null +++ b/test/fixtures/flora_magical_effects.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + flora_id: 1 + magic_id: 1 + +two: + flora_id: 1 + magic_id: 1 diff --git a/test/fixtures/flora_relationships.yml b/test/fixtures/flora_relationships.yml new file mode 100644 index 00000000..62e05d17 --- /dev/null +++ b/test/fixtures/flora_relationships.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + flora_id: 1 + related_flora_id: 1 + +two: + flora_id: 1 + related_flora_id: 1 diff --git a/test/fixtures/floras.yml b/test/fixtures/floras.yml new file mode 100644 index 00000000..02d14fc8 --- /dev/null +++ b/test/fixtures/floras.yml @@ -0,0 +1,39 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + description: MyString + aliases: MyString + order: MyString + family: MyString + genus: MyString + colorings: MyString + size: MyString + smell: MyString + taste: MyString + fruits: MyString + seeds: MyString + nuts: MyString + berries: MyString + medicinal_purposes: MyString + reproduction: MyString + seasonality: MyString + +two: + name: MyString + description: MyString + aliases: MyString + order: MyString + family: MyString + genus: MyString + colorings: MyString + size: MyString + smell: MyString + taste: MyString + fruits: MyString + seeds: MyString + nuts: MyString + berries: MyString + medicinal_purposes: MyString + reproduction: MyString + seasonality: MyString diff --git a/test/models/flora_eaten_by_test.rb b/test/models/flora_eaten_by_test.rb new file mode 100644 index 00000000..51f4a67b --- /dev/null +++ b/test/models/flora_eaten_by_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FloraEatenByTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/flora_location_test.rb b/test/models/flora_location_test.rb new file mode 100644 index 00000000..58b71f1b --- /dev/null +++ b/test/models/flora_location_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FloraLocationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/flora_magical_effect_test.rb b/test/models/flora_magical_effect_test.rb new file mode 100644 index 00000000..496fe370 --- /dev/null +++ b/test/models/flora_magical_effect_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FloraMagicalEffectTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/flora_relationship_test.rb b/test/models/flora_relationship_test.rb new file mode 100644 index 00000000..36513955 --- /dev/null +++ b/test/models/flora_relationship_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FloraRelationshipTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/flora_test.rb b/test/models/flora_test.rb new file mode 100644 index 00000000..2665bb12 --- /dev/null +++ b/test/models/flora_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class FloraTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end