th: Merge remote-tracking branch 'glitch/main' (5efa6ac771
)
This commit is contained in:
commit
1288d4c9b6
17 changed files with 73 additions and 83 deletions
|
@ -1,5 +1,6 @@
|
|||
[production]
|
||||
defaults
|
||||
not IE 11
|
||||
not dead
|
||||
|
||||
[development]
|
||||
|
|
|
@ -26,8 +26,7 @@ elasticsearch
|
|||
log
|
||||
neo4j
|
||||
node_modules
|
||||
postgres
|
||||
postgres14
|
||||
postgres*
|
||||
public/assets
|
||||
public/packs
|
||||
public/packs-test
|
||||
|
|
|
@ -51,7 +51,7 @@ REDIS_PORT=6379
|
|||
# PostgreSQL
|
||||
# ----------
|
||||
DB_HOST=db
|
||||
DB_USER=postgres
|
||||
DB_USER=mastodon
|
||||
DB_NAME=mastodon_production
|
||||
DB_PASS=
|
||||
DB_PORT=5432
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Contributing to Mastodon Glitch+Treehouse Edition #
|
||||
# Contributing to Mastodon Glitch+Treehouse Edition
|
||||
|
||||
Thank you for your interest in contributing to the **Treehouse Mastodon** project!
|
||||
Here are some guidelines, and ways you can help.
|
||||
|
||||
> (This document is a bit of a work-in-progress, so please bear with us.
|
||||
> If you don't see what you're looking for here, please don't hesitate to reach out!)
|
||||
> (This document is a bit of a work-in-progress, so please bear with us.
|
||||
> If you don't see what you're looking for here, please don't hesitate to reach out!)
|
||||
|
||||
## Translations
|
||||
|
||||
|
@ -12,31 +12,31 @@ You can submit glitch-soc-specific translations via [Crowdin](https://crowdin.co
|
|||
|
||||
[![Crowdin](https://badges.crowdin.net/glitch-soc/localized.svg)](https://crowdin.com/project/glitch-soc)
|
||||
|
||||
## Planning ##
|
||||
## Planning
|
||||
|
||||
Right now a lot of the planning for this project takes place in the `#fediverse`
|
||||
channel of the Treehouse Discord, or through Gitea Issues.
|
||||
|
||||
We're working on ways to improve the planning structure and better solicit feedback, and if you feel like you can help in this respect, feel free to give us a holler.
|
||||
|
||||
## Documentation ##
|
||||
## Documentation
|
||||
|
||||
The upstream Glitch documentation for this repository is available at [`glitch-soc/docs`](https://github.com/glitch-soc/docs) (online at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/)).
|
||||
|
||||
## Setup ##
|
||||
## Setup
|
||||
|
||||
For a some-batteries-required guide to setting up a development environment for this repository, read Rin's excellent
|
||||
[SETUP.md](https://gitea.treehouse.systems/treehouse/mastodon/src/branch/main/SETUP.md).
|
||||
|
||||
## Frontend Development ##
|
||||
## Frontend Development
|
||||
|
||||
Check out [the documentation here](https://glitch-soc.github.io/docs/contributing/frontend/) for more information.
|
||||
|
||||
## Backend Development ##
|
||||
## Backend Development
|
||||
|
||||
See the guidelines below.
|
||||
|
||||
- - -
|
||||
---
|
||||
|
||||
You should also try to follow the guidelines set out in the original `CONTRIBUTING.md` from `mastodon/mastodon`, reproduced below.
|
||||
|
||||
|
@ -85,8 +85,6 @@ It is not always possible to phrase every change in such a manner, but it is des
|
|||
- Code style rules (rubocop, eslint)
|
||||
- Normalization of locale files (i18n-tasks)
|
||||
|
||||
**Note**: You may need to log in and authorise the GitHub account your fork of this repository belongs to with CircleCI to enable some of the automated checks to run.
|
||||
|
||||
## Documentation
|
||||
|
||||
The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/documentation](https://github.com/mastodon/documentation).
|
||||
|
|
|
@ -6,7 +6,8 @@ So here's the deal: we all work on this code, and anyone who uses that does so a
|
|||
|
||||
Specifically, this fork-of-a-fork is intended for Treehouse use only. Unless
|
||||
otherwise communicated, we will not put effort into supporting other deployments
|
||||
or upstreaming our patches.
|
||||
or upstreaming our patches. This repo might be messy. Cleanliness of Git history
|
||||
is not guaranteed -- watch out for falling rebases regardless of A-button count!
|
||||
|
||||
## Links
|
||||
|
||||
|
@ -18,4 +19,4 @@ or upstreaming our patches.
|
|||
- Treehouse Social: [social.treehouse.systems](https://social.treehouse.systems)
|
||||
- VT Social: [vt.social](https://vt.social)
|
||||
- Unstable Systems: [unstable.systems](https://unstable.systems)
|
||||
- Slowest (dot) Network: [slowest.network](https://slowest.network)
|
||||
- Slowest (dot) Network: [slowest.network](https://slowest.network)
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
pin,
|
||||
unpin,
|
||||
} from 'flavours/glitch/actions/interactions';
|
||||
import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
import { initMuteModal } from 'flavours/glitch/actions/mutes';
|
||||
import { initReport } from 'flavours/glitch/actions/reports';
|
||||
|
@ -45,23 +46,22 @@ import {
|
|||
translateStatus,
|
||||
undoStatusTranslation,
|
||||
} from 'flavours/glitch/actions/statuses';
|
||||
import DetailedStatus from './components/detailed_status';
|
||||
import ActionBar from './components/action_bar';
|
||||
import Column from 'flavours/glitch/features/ui/components/column';
|
||||
import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
|
||||
import ColumnHeader from '../../components/column_header';
|
||||
import StatusContainer from 'flavours/glitch/containers/status_container';
|
||||
import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/initial_state';
|
||||
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
|
||||
import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
|
||||
import { textForScreenReader, defaultMediaVisibility } from 'flavours/glitch/components/status';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||
import { textForScreenReader, defaultMediaVisibility } from 'flavours/glitch/components/status';
|
||||
import ScrollContainer from 'flavours/glitch/containers/scroll_container';
|
||||
import StatusContainer from 'flavours/glitch/containers/status_container';
|
||||
import BundleColumnError from 'flavours/glitch/features/ui/components/bundle_column_error';
|
||||
import Column from 'flavours/glitch/features/ui/components/column';
|
||||
import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/initial_state';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
|
||||
import { autoUnfoldCW } from 'flavours/glitch/utils/content_warning';
|
||||
|
||||
import ColumnHeader from '../../components/column_header';
|
||||
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
|
||||
|
||||
import ActionBar from './components/action_bar';
|
||||
import DetailedStatus from './components/detailed_status';
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
|
|
|
@ -525,7 +525,6 @@ export default function compose(state = initialState, action) {
|
|||
return item;
|
||||
}));
|
||||
case INIT_MEDIA_EDIT_MODAL:
|
||||
{
|
||||
const media = state.get('media_attachments').find(item => item.get('id') === action.id);
|
||||
return state.set('media_modal', ImmutableMap({
|
||||
id: action.id,
|
||||
|
@ -534,7 +533,6 @@ export default function compose(state = initialState, action) {
|
|||
focusY: media.getIn(['meta', 'focus', 'y'], 0),
|
||||
dirty: false,
|
||||
}));
|
||||
}
|
||||
case COMPOSE_CHANGE_MEDIA_DESCRIPTION:
|
||||
return state.setIn(['media_modal', 'description'], action.description).setIn(['media_modal', 'dirty'], true);
|
||||
case COMPOSE_CHANGE_MEDIA_FOCUS:
|
||||
|
@ -590,7 +588,6 @@ export default function compose(state = initialState, action) {
|
|||
case COMPOSE_DOODLE_SET:
|
||||
return state.mergeIn(['doodle'], action.options);
|
||||
case REDRAFT:
|
||||
{
|
||||
const do_not_federate = !!action.status.get('local_only');
|
||||
let text = action.raw_text || unescapeHTML(expandMentions(action.status));
|
||||
if (do_not_federate) text = text.replace(/ ?👁\ufe0f?\u200b?$/, '');
|
||||
|
@ -631,7 +628,6 @@ export default function compose(state = initialState, action) {
|
|||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
case COMPOSE_SET_STATUS:
|
||||
return state.withMutations(map => {
|
||||
map.set('id', action.status.get('id'));
|
||||
|
|
|
@ -57,14 +57,11 @@ import {
|
|||
translateStatus,
|
||||
undoStatusTranslation,
|
||||
} from '../../actions/statuses';
|
||||
|
||||
import ColumnHeader from '../../components/column_header';
|
||||
import { textForScreenReader, defaultMediaVisibility } from '../../components/status';
|
||||
import StatusContainer from '../../containers/status_container';
|
||||
|
||||
import { boostModal, deleteModal } from '../../initial_state';
|
||||
import { makeGetStatus, makeGetPictureInPicture } from '../../selectors';
|
||||
|
||||
import Column from '../ui/components/column';
|
||||
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
|
||||
|
||||
|
|
|
@ -110,27 +110,25 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
def process_status_params
|
||||
@status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url)
|
||||
|
||||
@params = begin
|
||||
{
|
||||
uri: @status_parser.uri,
|
||||
url: @status_parser.url || @status_parser.uri,
|
||||
account: @account,
|
||||
text: converted_object_type? ? converted_text : (@status_parser.text || ''),
|
||||
language: @status_parser.language,
|
||||
spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
|
||||
created_at: @status_parser.created_at,
|
||||
edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
|
||||
override_timestamps: @options[:override_timestamps],
|
||||
reply: @status_parser.reply,
|
||||
sensitive: @account.sensitized? || @status_parser.sensitive || false,
|
||||
visibility: @status_parser.visibility,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
poll: process_poll,
|
||||
quote: process_quote,
|
||||
}
|
||||
end
|
||||
@params = {
|
||||
uri: @status_parser.uri,
|
||||
url: @status_parser.url || @status_parser.uri,
|
||||
account: @account,
|
||||
text: converted_object_type? ? converted_text : (@status_parser.text || ''),
|
||||
language: @status_parser.language,
|
||||
spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
|
||||
created_at: @status_parser.created_at,
|
||||
edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
|
||||
override_timestamps: @options[:override_timestamps],
|
||||
reply: @status_parser.reply,
|
||||
sensitive: @account.sensitized? || @status_parser.sensitive || false,
|
||||
visibility: @status_parser.visibility,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
poll: process_poll,
|
||||
quote: process_quote,
|
||||
}
|
||||
end
|
||||
|
||||
def process_audience
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#
|
||||
# Table name: accounts
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# username :string default(""), not null
|
||||
# domain :string
|
||||
# private_key :text
|
||||
|
@ -16,11 +17,11 @@
|
|||
# url :string
|
||||
# avatar_file_name :string
|
||||
# avatar_content_type :string
|
||||
# avatar_file_size :bigint(8)
|
||||
# avatar_file_size :integer
|
||||
# avatar_updated_at :datetime
|
||||
# header_file_name :string
|
||||
# header_content_type :string
|
||||
# header_file_size :bigint(8)
|
||||
# header_file_size :integer
|
||||
# header_updated_at :datetime
|
||||
# avatar_remote_url :string
|
||||
# locked :boolean default(FALSE), not null
|
||||
|
@ -31,7 +32,6 @@
|
|||
# shared_inbox_url :string default(""), not null
|
||||
# followers_url :string default(""), not null
|
||||
# protocol :integer default("ostatus"), not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# memorial :boolean default(FALSE), not null
|
||||
# moved_to_account_id :bigint(8)
|
||||
# featured_collection_url :string
|
||||
|
@ -45,8 +45,8 @@
|
|||
# avatar_storage_schema_version :integer
|
||||
# header_storage_schema_version :integer
|
||||
# devices_url :string
|
||||
# sensitized_at :datetime
|
||||
# suspension_origin :integer
|
||||
# sensitized_at :datetime
|
||||
# trendable :boolean
|
||||
# reviewed_at :datetime
|
||||
# requested_review_at :datetime
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# domain :string
|
||||
# image_file_name :string
|
||||
# image_content_type :string
|
||||
# image_file_size :bigint(8)
|
||||
# image_file_size :integer
|
||||
# image_updated_at :datetime
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
#
|
||||
# Table name: imports
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# type :integer not null
|
||||
# approved :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# data_file_name :string
|
||||
# data_content_type :string
|
||||
# data_file_size :bigint(8)
|
||||
# data_file_size :integer
|
||||
# data_updated_at :datetime
|
||||
# account_id :bigint(8) not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# overwrite :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
#
|
||||
# Table name: media_attachments
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# status_id :bigint(8)
|
||||
# file_file_name :string
|
||||
# file_content_type :string
|
||||
# file_file_size :bigint(8)
|
||||
# file_file_size :integer
|
||||
# file_updated_at :datetime
|
||||
# remote_url :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
|
@ -16,7 +17,6 @@
|
|||
# type :integer default("image"), not null
|
||||
# file_meta :json
|
||||
# account_id :bigint(8)
|
||||
# id :bigint(8) not null, primary key
|
||||
# description :text
|
||||
# scheduled_status_id :bigint(8)
|
||||
# blurhash :string
|
||||
|
@ -24,7 +24,7 @@
|
|||
# file_storage_schema_version :integer
|
||||
# thumbnail_file_name :string
|
||||
# thumbnail_content_type :string
|
||||
# thumbnail_file_size :bigint(8)
|
||||
# thumbnail_file_size :integer
|
||||
# thumbnail_updated_at :datetime
|
||||
# thumbnail_remote_url :string
|
||||
#
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# description :string default(""), not null
|
||||
# image_file_name :string
|
||||
# image_content_type :string
|
||||
# image_file_size :bigint(8)
|
||||
# image_file_size :integer
|
||||
# image_updated_at :datetime
|
||||
# type :integer default("link"), not null
|
||||
# html :text default(""), not null
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# var :string default(""), not null
|
||||
# file_file_name :string
|
||||
# file_content_type :string
|
||||
# file_file_size :bigint(8)
|
||||
# file_file_size :integer
|
||||
# file_updated_at :datetime
|
||||
# meta :json
|
||||
# created_at :datetime not null
|
||||
|
|
|
@ -100,7 +100,7 @@ class User < ApplicationRecord
|
|||
validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? }
|
||||
validates_with EmailMxValidator, if: :validate_email_dns?
|
||||
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
|
||||
# validates :time_zone, inclusion: { in: ActiveSupport::TimeZone.all.map { |tz| tz.tzinfo.name } }, allow_blank: true
|
||||
validates :time_zone, inclusion: { in: ActiveSupport::TimeZone.all.map { |tz| tz.tzinfo.name } }, allow_blank: true
|
||||
|
||||
# Honeypot/anti-spam fields
|
||||
attr_accessor :registration_form_time, :website, :confirm_password
|
||||
|
|
30
db/schema.rb
30
db/schema.rb
|
@ -153,11 +153,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.string "url"
|
||||
t.string "avatar_file_name"
|
||||
t.string "avatar_content_type"
|
||||
t.bigint "avatar_file_size"
|
||||
t.integer "avatar_file_size"
|
||||
t.datetime "avatar_updated_at", precision: nil
|
||||
t.string "header_file_name"
|
||||
t.string "header_content_type"
|
||||
t.bigint "header_file_size"
|
||||
t.integer "header_file_size"
|
||||
t.datetime "header_updated_at", precision: nil
|
||||
t.string "avatar_remote_url"
|
||||
t.boolean "locked", default: false, null: false
|
||||
|
@ -181,8 +181,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.integer "avatar_storage_schema_version"
|
||||
t.integer "header_storage_schema_version"
|
||||
t.string "devices_url"
|
||||
t.datetime "sensitized_at", precision: nil
|
||||
t.integer "suspension_origin"
|
||||
t.datetime "sensitized_at", precision: nil
|
||||
t.boolean "trendable"
|
||||
t.datetime "reviewed_at", precision: nil
|
||||
t.datetime "requested_review_at", precision: nil
|
||||
|
@ -355,7 +355,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.string "domain"
|
||||
t.string "image_file_name"
|
||||
t.string "image_content_type"
|
||||
t.bigint "image_file_size"
|
||||
t.integer "image_file_size"
|
||||
t.datetime "image_updated_at", precision: nil
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
|
@ -522,7 +522,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.string "data_file_name"
|
||||
t.string "data_content_type"
|
||||
t.bigint "data_file_size"
|
||||
t.integer "data_file_size"
|
||||
t.datetime "data_updated_at", precision: nil
|
||||
t.bigint "account_id", null: false
|
||||
t.boolean "overwrite", default: false, null: false
|
||||
|
@ -543,12 +543,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
end
|
||||
|
||||
create_table "ip_blocks", force: :cascade do |t|
|
||||
t.inet "ip", default: "0.0.0.0", null: false
|
||||
t.integer "severity", default: 0, null: false
|
||||
t.datetime "expires_at", precision: nil
|
||||
t.text "comment", default: "", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.datetime "expires_at", precision: nil
|
||||
t.inet "ip", default: "0.0.0.0", null: false
|
||||
t.integer "severity", default: 0, null: false
|
||||
t.text "comment", default: "", null: false
|
||||
t.index ["ip"], name: "index_ip_blocks_on_ip", unique: true
|
||||
end
|
||||
|
||||
|
@ -599,7 +599,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.bigint "status_id"
|
||||
t.string "file_file_name"
|
||||
t.string "file_content_type"
|
||||
t.bigint "file_file_size"
|
||||
t.integer "file_file_size"
|
||||
t.datetime "file_updated_at", precision: nil
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
|
@ -615,7 +615,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.integer "file_storage_schema_version"
|
||||
t.string "thumbnail_file_name"
|
||||
t.string "thumbnail_content_type"
|
||||
t.bigint "thumbnail_file_size"
|
||||
t.integer "thumbnail_file_size"
|
||||
t.datetime "thumbnail_updated_at", precision: nil
|
||||
t.string "thumbnail_remote_url"
|
||||
t.index ["account_id", "status_id"], name: "index_media_attachments_on_account_id_and_status_id", order: { status_id: :desc }
|
||||
|
@ -783,7 +783,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.string "description", default: "", null: false
|
||||
t.string "image_file_name"
|
||||
t.string "image_content_type"
|
||||
t.bigint "image_file_size"
|
||||
t.integer "image_file_size"
|
||||
t.datetime "image_updated_at", precision: nil
|
||||
t.integer "type", default: 0, null: false
|
||||
t.text "html", default: "", null: false
|
||||
|
@ -895,7 +895,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
t.string "var", default: "", null: false
|
||||
t.string "file_file_name"
|
||||
t.string "file_content_type"
|
||||
t.bigint "file_file_size"
|
||||
t.integer "file_file_size"
|
||||
t.datetime "file_updated_at", precision: nil
|
||||
t.json "meta"
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
|
@ -933,8 +933,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do
|
|||
create_table "status_pins", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "status_id", null: false
|
||||
t.datetime "created_at", precision: nil, default: -> { "CURRENT_TIMESTAMP" }, null: false
|
||||
t.datetime "updated_at", precision: nil, default: -> { "CURRENT_TIMESTAMP" }, null: false
|
||||
t.datetime "created_at", precision: nil, default: -> { "now()" }, null: false
|
||||
t.datetime "updated_at", precision: nil, default: -> { "now()" }, null: false
|
||||
t.index ["account_id", "status_id"], name: "index_status_pins_on_account_id_and_status_id", unique: true
|
||||
t.index ["status_id"], name: "index_status_pins_on_status_id"
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue