mysql - 将不同语言的post表的2个相同id存储到数据库中

标签 mysql database laravel multilingual

我正在构建一个多语言网站。在本例中,只有 2 种语言,即使用 Laravel 的印度尼西亚语和英语。 我有 posts 表,它将存储每个帖子的 id,post_translations 表用于存储帖子的本地、标题和描述。 我在将数据存储到数据库时遇到问题。我不知道如何在不包含 id 的情况下存储帖子,除了我添加了 2 个相同的印度尼西亚语和英语帖子。

这是结果(错误)

帖子表

id 
1
2

post_translations 表

id  post_id  locale   title
1     1      en       fisrt post
2     2      id       post yang pertama

预期结果

帖子表

id 
1

post_translations 表

id  post_id  locale   title
1     1      en       fisrt post
2     1      id       post yang pertama

后 Controller

  public function store(Request $request) {
    $this->validate($request, [
        'title' => 'required',
        'slug' => 'required',
        'content' => 'required'
    ]);

    $post = new Post;

    $post->title = $request->title;
    $post->slug = $request->slug;
    $post->content = $request->content;

    $post->save();
    return redirect()->route('post.index');
}

最佳答案

好的,我们开始吧(请注意,这不是唯一的方法):

  1. 安装 spatie/laravel-translatable

    Composer 需要 spatie/laravel-translatable

**注意:对于 native spatie/laravel-translatable,请转到版本 2 **

  • 创建具有以下结构的表:

    创建表文章 ( id int(10) 无符号非空, 标题文本整理utf8_unicode_ci, slug 文本整理 utf8_unicode_ci, 内容文本整理utf8_unicode_ci, created_at 时间戳 NULL DEFAULT NULL, updated_at 时间戳 NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

  • 注意:最好使用迁移。我刚刚导出了之前做的一个表来测试

  • 将数据以 json 格式插入数据库,如下所示:
  •     INSERT INTO `pages` (`id`, `title`, `slug`, `content`, `created_at`, `updated_at`) VALUES
            (1, '{"ro":"Acas\\u0103","en":"Home"}', NULL, '{"ro":"<p><strong>Test title<\\/strong><\\/p>\\r\\n\\r\\n<p>Test content romanian<\\/p>\\r\\n","en":"<p><strong>test title english<\\/strong><\\/p>\\r\\n\\r\\n<p>test content english.<\\/p>\\r\\n"}', '2017-04-03 11:45:56', '2017-04-03 12:15:16');

  • 现在创建 Blade 以编辑、更新、创建节目等。要获取语言,请在 Blade 中执行以下操作:

    {{ $data->标题 }}

    {!! nl2br($data->内容)!!}

  • 在 Controller 中: 添加类似这样的内容:

    /** * 按语言生成字段 * * @param Model $entry 从数据库中选择的项目 * * @返回数组 */

    public function getTranslatableFields($fields)
    {
        $inputs = [];
        $languages = $this->getLanguages();
    
        foreach ($languages as $language) {
            foreach ($fields as $field) {
                $inputs[] = [
                    'name' => "{$field['name']}[{$language->abbr}]",
                    'label' => $field['label'] . " ($language->abbr)",
                    'lang' => $language->abbr,
                    'type' => array_key_exists('type', $field) ?     $field['type'] : 'text'
                ];
            }
        }
    
        return $inputs;
    }
    
  • 我在 LangTrait 中添加了这个函数。由于我也使用 Laravel 背包,所以我做了更多的事情。

    为了编辑,我在特征中添加了这个方法:

    /**
         * Show the form for editing the specified resource.
         *
         * @param   int             $id             the item's identifier
         *
         * @return  Response
         */
        public function edit($id)
        {    
            $data['entry'] = Model::find($id);
            $data['title'] = trans('lang_file.edit').' '.$this->entity_name; // name of the page 
            $data['fields'] = $this->getMultiLangFields($data['entry']);
            $data['id'] = $id;
    
            return view('crud::edit', $data);
        }
    
    
    /**
         * Generate the field by language
         *
         * @param   Model        $entry      the item selected from the database
         *
         * @return  array
         */
        protected function getMultiLangFields($entry)
        {
            $fields['id'] = ['name' => 'id', 'type' => 'hidden', 'value' => $entry->id];
    
            foreach ($this->crud->update_fields as $key => $field) {
                $value = null;
    
                if (array_key_exists('lang', $field)) {
                    $name = preg_replace('/(\[\w{2}\])$/i', '', $field['name']);
                    $value = $entry->getTranslation($name, $field['lang']);
                }
    
                $fields[$key] = array_merge($field, ['value' => $value]);
            }
    
            return $fields;
        }
    
    
    
    /**
         * Get the application active languages
         *
         * @return  \Backpack\LangFileManager\app\Models\Language
         */
        protected function getLanguages()
        {
            return Language::whereActive(1)->orderBy('default', 'desc')->get();
        }
    
  • 最后在我的主 Controller 中我做了: use LangTrait;(包含以上所有内容)
  • 在构造中我添加了这个:

    $this->getTranslatableFields($fields)
    

    其中 $fields 是我需要的字段列表

    所有方法都应该适应您的 html 格式。正如我所说,我使用 Laravel 的背包,字段的格式也相应地

  • 最后,为了使 getLanguage 文件正常工作,我在数据库中创建了一个新表和一个模型:
  • 型号:

    class Language extends Model
    {
        protected $table = 'languages';
    
        protected $fillable = ['name', 'flag', 'abbr', 'native', 'active', 'default'];
    
        public $timestamps = false;
    
        public static function getActiveLanguagesArray()
        {
            $active_languages = self::where('active', 1)->get()->toArray();
            $localizable_languages_array = [];
    
            if (count($active_languages)) {
                foreach ($active_languages as $key => $lang) {
                    $localizable_languages_array[$lang['abbr']] = $lang;
                }
    
                return $localizable_languages_array;
            }
    
            return config('laravellocalization.supportedLocales');
        }
    
        public static function findByAbbr($abbr = false)
        {
            return self::where('abbr', $abbr)->first();
        }
    }
    

    表:

    CREATE TABLE `languages` (
      `id` int(10) UNSIGNED NOT NULL,
      `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
      `app_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
      `flag` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
      `abbr` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
      `script` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
      `native` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
      `active` tinyint(3) UNSIGNED NOT NULL DEFAULT '1',
      `default` tinyint(3) UNSIGNED NOT NULL DEFAULT '0',
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL,
      `deleted_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    

    表中数据:

    INSERT INTO `languages` (`id`, `name`, `app_name`, `flag`, `abbr`, `script`, `native`, `active`, `default`, `created_at`, `updated_at`, `deleted_at`) VALUES
    (1, 'English', 'english', '', 'en', 'Latn', 'English', 1, 0, NULL, NULL, NULL),
    (2, 'Romanian', 'romanian', '', 'ro', 'Latn', 'română', 1, 1, NULL, NULL, NULL);
    

    由于我是通过一个包来完成此操作的,所以我对代码做了一些改动。

    <小时/>

    现在,对于 spatie/laravel-translatable 包版本:

    1. 在 config/app.php 中设置服务提供者,并将其添加到提供者数组中:

      Spatie\Translatable\TranslatableServiceProvider::class,

    在模型文章中添加use HasTranslations;,如下所示:

    use Illuminate\Database\Eloquent\Model;
    use Spatie\Translatable\HasTranslations;
    
    class NewsItem extends Model
    {
        use HasTranslations;
    
        public $translatable = ['name']; // list the columns you want to be translatable (will have json format)
    }
    
  • 保存新条目并使用它:

    $article = 新文章; $article->setTranslation('name', 'en', '更新英文名称') ->setTranslation('name', 'nl', 'Naam in het Nederlands');

    $article->save();

    $文章->名称;//鉴于当前应用程序区域设置为“en”,返回“英文名称” $article->getTranslation('name', 'nl');//返回“Naam in het Nederlands”

    app()->setLocale('nl');

    $文章->名称;//返回“Naam in het Nederlands”

  • 示例来自:https://github.com/spatie/laravel-translatable

  • 数据库表格式如上面第一个版本中所述

  • 如果不起作用请告诉我,我会查看您的代码。

    关于mysql - 将不同语言的post表的2个相同id存储到数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43143857/

    相关文章:

    php - 从数据库中删除文件或照片时如何从文件夹中删除它?

    php - 通过长队列运行多个工作人员

    php - 如何从数据库中检索信息

    mysql - 在 MySQL 中为给定数据库创建用户?

    java - 是否需要 Class.forName() 机制?

    php - 用户 ID 和用户名未插入关系

    mysql - 使用 MySQL 从表中删除整行

    java - 如何将 json 字符串作为 RESTFUL 请求发送给 postman

    java - 将日期选择器转换为字符串

    Laravel 如何在主模板文件中包含的所有 View 中传递数据?