You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在WatermelonDB模型类外调用@writer方法失败求助

问题原因与解决方案

你的核心问题是对WatermelonDB的模型与集合的方法归属理解错误:你在Post模型类里定义的createPost和updatePost是模型实例方法(属于单个Post对象),但你在组件里试图从postCollection(集合对象)上去调用这些方法,自然找不到。

另外原模型代码的逻辑也不合理:创建新Post的方法不该写在模型实例里(因为创建时还没有实例),更新方法也不该在一个实例里去查找另一个实例。


方案一:直接使用WatermelonDB原生API(推荐)

不需要自定义模型方法,直接用集合的原生create和模型实例的update方法,它们本身就支持事务处理:

修改组件代码

export const Style = () => {
  const database = useDatabase();
  const postCollection = database.collections.get<Post>('posts');

  // 创建Post
  const createPost = async (newPost: PostType) => {
    try {
      await postCollection.create(post => {
        post.postId = newPost.postId;
        post.rowModifiedAt = newPost.rowModifiedAt;
        post.title = newPost.title;
        post.body = newPost.body;
      });
      console.log('Post created successfully');
    } catch (error) {
      console.error('Error creating post:', error);
    }
  };

  // 更新Post
  const updatePost = async (postData: PostType) => {
    try {
      // 先找到要更新的Post实例
      const targetPost = await postCollection.find(String(postData.postId));
      await targetPost.update(post => {
        // 注意:postId作为主键不建议修改
        post.rowModifiedAt = postData.rowModifiedAt;
        post.title = postData.title;
        post.body = postData.body;
      });
      console.log('Post updated successfully');
    } catch (error) {
      console.error('Error updating post:', error);
    }
  };

  // ... 其他组件逻辑
};

方案二:封装方法到集合类(如果需要自定义封装)

如果你希望把创建/更新逻辑封装成集合的方法,可以扩展Collection类:

1. 创建自定义集合类

// post-collection.ts
import { Collection } from '@nozbe/watermelondb';
import { writer } from '@nozbe/watermelondb/decorators';
import Post from './Post';
import PostType from '@/data/types/post';

export class PostCollection extends Collection<Post> {
  @writer async createPost(postData: PostType) {
    return await this.create(post => {
      post.postId = postData.postId;
      post.rowModifiedAt = postData.rowModifiedAt;
      post.title = postData.title;
      post.body = postData.body;
    });
  }

  @writer async updatePost(postData: PostType) {
    const targetPost = await this.find(String(postData.postId));
    await targetPost.update(post => {
      post.rowModifiedAt = postData.rowModifiedAt;
      post.title = postData.title;
      post.body = postData.body;
    });
  }
}

2. 数据库初始化时绑定自定义集合

// database.ts
import { Database } from '@nozbe/watermelondb';
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
import schema from './schema';
import Post from './models/Post';
import { PostCollection } from './models/post-collection';

const adapter = new SQLiteAdapter({ schema });

const database = new Database({
  adapter,
  modelClasses: [Post],
  // 绑定自定义集合类
  collectionClasses: {
    posts: PostCollection,
  },
});

export default database;

3. 组件中调用自定义方法

export const Style = () => {
  const database = useDatabase();
  // 断言类型为自定义的PostCollection
  const postCollection = database.collections.get<Post>('posts') as PostCollection;

  const createPost = async (newPost: PostType) => {
    try {
      await postCollection.createPost(newPost);
      console.log('Post created successfully');
    } catch (error) {
      console.error('Error creating post:', error);
    }
  };

  // ... 其他组件逻辑
};

内容的提问来源于stack exchange,提问作者Smeagol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:53:30