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

Angular5对接Rails5+Shrine:如何通过tus-js-client传递匹配的name属性

Solution for Matching Tus-Uppy Upload Params with Rails 5 + Shrine

Let's break down how to get your Angular 5 + Rails 5 + Shrine + Uppy/tus setup working correctly, focusing on aligning frontend params with Rails' strong parameters.

Key Background

The core issue here is that Rails expects nested parameters (like movie[title] or a top-level movie object containing all fields) to map to your model, and Shrine relies on a video_data parameter to attach the uploaded file. Since you're using Uppy's built-in submission instead of Rails forms, we need to explicitly shape the data sent to Rails.

Step 1: Frontend Uppy Configuration

You have two reliable approaches to structure your requests correctly:

Option A: Manual Request After Tus Upload

Use Uppy's complete hook to handle file upload success, then send structured movie data (including Shrine-generated video_data) to your /movies endpoint:

// Initialize Uppy with Tus plugin
const uppy = Uppy.Core({ debug: true })
  .use(Uppy.Tus, {
    endpoint: '/files', // Your Shrine tus endpoint
    retryDelays: [0, 3000, 5000, 10000],
    headers: {
      'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
    }
  });

// Handle upload completion
uppy.on('complete', (result) => {
  if (result.successful.length === 0) return;

  const uploadedFile = result.successful[0];
  // Extract video_data from the uploaded file's metadata (adjust based on your Shrine setup)
  const videoData = uploadedFile.meta.video_data;

  // Gather form fields
  const movieData = {
    title: document.getElementById('movie-title').value,
    year: document.getElementById('movie-year').value,
    plot: document.getElementById('movie-plot').value,
    video_data: videoData
  };

  // Send structured request to Rails
  fetch('/movies', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
    },
    body: JSON.stringify({ movie: movieData })
  })
  .then(res => res.json())
  .then(data => console.log('Movie created:', data))
  .catch(err => console.error('Error:', err));
});

Option B: Use Uppy Form Plugin for Field Mapping

If you want Uppy to handle form field collection, set your HTML inputs to use Rails-friendly name attributes, then configure the Form plugin:

<form id="movie-upload-form">
  <input type="text" id="title" name="movie[title]" required>
  <input type="number" id="year" name="movie[year]" required>
  <textarea id="plot" name="movie[plot]"></textarea>
  <div id="uppy-target"></div>
</form>
const uppy = Uppy.Core()
  .use(Uppy.Form, { target: '#movie-upload-form', submitOnSuccess: false })
  .use(Uppy.Tus, {
    endpoint: '/files',
    headers: { 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content }
  });

uppy.on('submit', (result) => {
  if (result.successful.length === 0) return;

  // Build FormData with Rails-compatible params
  const formData = new FormData();
  const movieMeta = uppy.getState().meta;

  // Add form fields
  Object.keys(movieMeta).forEach(key => {
    if (key.startsWith('movie[')) formData.append(key, movieMeta[key]);
  });

  // Add video_data from the uploaded file
  formData.append('movie[video_data]', result.successful[0].meta.video_data);

  // Submit to Rails
  fetch('/movies', {
    method: 'POST',
    body: formData,
    headers: {
      'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
    }
  });
});

Step 2: Rails Backend Adjustments

Update your movie_params to accept the video_data field (this is what Shrine uses to attach the uploaded file):

# app/controllers/movies_controller.rb
def create
  movie = Movie.new(movie_params)
  if movie.save
    render json: movie, status: :created
  else
    render json: { errors: movie.errors }, status: :unprocessable_entity
  end
end

private

def movie_params
  # Permit the fields you need, including video_data for Shrine
  params.require(:movie).permit(:title, :year, :plot, :video_data)
end

Ensure your Sequel model is set up correctly with Shrine:

# app/models/movie.rb
class Movie < Sequel::Model
  include VideoUploader::Attachment.new(:video)
end

Step 3: Verify and Debug

  • Check your Rails server logs to inspect incoming Parameters: – this is critical for debugging. If you see flat params like {"title"=>"Test"} instead of nested {"movie"=>{"title"=>"Test"}}, adjust your frontend request structure.
  • Confirm your Shrine tus endpoint returns video_data after a successful upload. Test this by directly uploading a file to /files and checking the response.
  • Make sure the Rails CSRF token is included in all POST requests – missing this will trigger 422 errors.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:35:10