<p>Thanks for that tip, Lindsey, but here's what happened: I changed <code>calendar37</code> to <code>calendar37_Occurrences</code> and then all three tables wouldn't uninstall.  It turns out that the issue is having a capital letter after the underscore.  So it seems like an "undocumented feature" that you can make plugin tables persist after uninstall by including a capital letter after the underscore.</p>

<pre><code>return 'calendar37_Subsets';
return 'calendar37_Views';
</code></pre>

<p>needed to become:</p>

<pre><code>return 'calendar37_subsets';
return 'calendar37_views';
</code></pre>

CC BY-SA 3.0
2015-12-08T19:02:41.203Z
Glad you figured it out! I'd actually call that a bug more than a feature... If Craft decides to install a table, it should be equally willing to uninstall it.
Lindsey D
CC BY-SA 3.0
2015-12-08T18:37:54.843Z
2015-12-08T18:37:54.843Z
kr37
<p>This is a little bit speculative, so let me know if it turns out to be incorrect...</p>

<p>When you use a <strong>non-underscored</strong> Record name, you're telling Craft that this is the one-and-only, definitive Record. When you use an <strong>underscored</strong> Record name, you're telling Craft that this Record is one-of-many. I have a vague recollection of similar behavior with Variables or Controllers too.</p>

<p>Hard to say if that would be considered a "bug" or a "feature". Pixel &amp; Tonic may have a sound reason why that restriction exists.</p>

CC BY-SA 3.0
2015-12-08T07:40:33.723Z
2015-12-08T07:40:33.723Z
Lindsey D
<p>When uninstalling my plugin, only one table is removed. Two others are left behind.  Any suggestions what I'm doing wrong?  Could it be naming with and without the underscore?</p>

<p>The good:</p>

<pre><code>&lt;?php
namespace Craft;

class Calendar37Record extends BaseRecord
{
    public function getTableName() {
        return 'calendar37';
    }
    protected function defineAttributes() { 
        return array(
            'event_id'   =&gt; AttributeType::Number,
            'dateYmd'    =&gt; AttributeType::String,
            'timestr'    =&gt; AttributeType::String,
            'alt_text'   =&gt; AttributeType::String,
            'css_class'  =&gt; AttributeType::String,
            'userJson'   =&gt; AttributeType::String,
        );
    }
    public function defineIndexes() {
        return array(
            array('columns' =&gt; array('event_id', 'dateYmd'), 'key' =&gt; true),
        );
    }
}
</code></pre>

<p>and the bad:</p>

<pre><code>&lt;?php
namespace Craft;

class Calendar37_SubsetsRecord extends BaseRecord
{
    public function getTableName() {
        return 'calendar37_Subsets';
    }
    protected function defineAttributes() { 
        return array(
            'handle'              =&gt; AttributeType::String,
            'title'               =&gt; AttributeType::String,
            'categoriesToInclude' =&gt; AttributeType::String,
            'categoriesToExclude' =&gt; AttributeType::String,
            );
    }
    public function defineIndexes() {
        return array(
            array('columns' =&gt; array('handle'), 'unique' =&gt; true),
        );
    }
}
</code></pre>

<p>Bad #2:</p>

<pre><code>&lt;?php
namespace Craft;

class Calendar37_ViewsRecord extends BaseRecord
{
    public function getTableName() {
        return 'calendar37_Views';
    }
    protected function defineAttributes() { 
        return array(
            'subsetId'     =&gt; AttributeType::String,
            'startDateYmd' =&gt; AttributeType::String,
            'endDateYmd'   =&gt; AttributeType::String,
            'htmlBefore'   =&gt; array(AttributeType::String, 'column' =&gt; ColumnType::Text, 'required' =&gt; false),
            'htmlAfter'    =&gt; array(AttributeType::String, 'column' =&gt; ColumnType::Text, 'required' =&gt; false),
        );
    }
    public function defineIndexes() {
        return array(
            array('columns' =&gt; array('subsetId', 'startDateYmd' ), 'key' =&gt; true),
        );
    }
}
</code></pre>

<plugin-development><records><uninstall>
Plugin uninstall only removes one table
# Plugin uninstall only removes one table

(Asked by: username_0 on 2015-12-08)

When uninstalling my plugin, only one table is removed. Two others are left behind.  Any suggestions what I'm doing wrong?  Could it be naming with and without the underscore?
The good:
 AttributeType::Number,
            'dateYmd'    => AttributeType::String,
            'timestr'    => AttributeType::String,
            'alt_text'   => AttributeType::String,
            'css_class'  => AttributeType::String,
            'userJson'   => AttributeType::String,
        );
    }
    public function defineIndexes() {
        return array(
            array('columns' => array('event_id', 'dateYmd'), 'key' => true),
        );
    }
}

and the bad:
 AttributeType::String,
            'title'               => AttributeType::String,
            'categoriesToInclude' => AttributeType::String,
            'categoriesToExclude' => AttributeType::String,
            );
    }
    public function defineIndexes() {
        return array(
            array('columns' => array('handle'), 'unique' => true),
        );
    }
}

Bad #2:
 AttributeType::String,
            'startDateYmd' => AttributeType::String,
            'endDateYmd'   => AttributeType::String,
            'htmlBefore'   => array(AttributeType::String, 'column' => ColumnType::Text, 'required' => false),
            'htmlAfter'    => array(AttributeType::String, 'column' => ColumnType::Text, 'required' => false),
        );
    }
    public function defineIndexes() {
        return array(
            array('columns' => array('subsetId', 'startDateYmd' ), 'key' => true),
        );
    }
}

**Tags:** plugin-development, records, uninstall

---

## 2 answers

### Answer by username_0 on 2015-12-08. Score: 2 | Accepted answer

Thanks for that tip, Lindsey, but here's what happened: I changed calendar37 to calendar37_Occurrences and then all three tables wouldn't uninstall.  It turns out that the issue is having a capital letter after the underscore.  So it seems like an "undocumented feature" that you can make plugin tables persist after uninstall by including a capital letter after the underscore.
return 'calendar37_Subsets';
return 'calendar37_Views';

needed to become:
return 'calendar37_subsets';
return 'calendar37_views';

> **Comments:**
> **username_1**: Glad you figured it out! I'd actually call that a bug more than a feature... If Craft decides to install a table, it should be equally willing to uninstall it.  

---

### Answer by username_1 on 2015-12-08. Score: 1

This is a little bit speculative, so let me know if it turns out to be incorrect...

When you use a **non-underscored** Record name, you're telling Craft that this is the one-and-only, definitive Record. When you use an **underscored** Record name, you're telling Craft that this Record is one-of-many. I have a vague recollection of similar behavior with Variables or Controllers too.

Hard to say if that would be considered a "bug" or a "feature". Pixel & Tonic may have a sound reason why that restriction exists.


---

