RoR应用文件选择上传功能求助:仅显示上传按钮
Got it, let's walk through getting file uploads fully working in your Rails app—from letting users select local files to saving them (either to your database via Active Storage or server-side, though we'll focus on the Rails-native approach since you're using PostgreSQL and Heroku). Here's a step-by-step breakdown tailored to your setup:
1. Update Your View (project.html.erb)
Right now you just have an upload button—you need to wrap it in a form with the multipart: true attribute (critical for file uploads) and add a file input field.
If you're submitting to a specific controller action (let's say static_pages#submit_project), use form_with like this:
<%= form_with(url: submit_project_path, method: :post, multipart: true) do |form| %> <!-- Add your existing form fields here (if any) --> <!-- File upload field --> <div class="form-group"> <%= form.label :uploaded_file, "Select File" %> <%= form.file_field :uploaded_file, class: "form-control" %> </div> <!-- Submit button --> <%= form.submit "Submit Form", class: "btn btn-primary" %> <% end %>
If you're using a model-backed form (e.g., a Project model), adjust it to use form_for or form_with(model: @project) instead—just make sure multipart: true is included.
2. Set Up Active Storage (Rails' Native File Upload Tool)
Rails has built-in Active Storage for handling file uploads, which integrates seamlessly with PostgreSQL and Heroku. Here's how to set it up:
Install Active Storage
Run these commands locally:
rails active_storage:install rails db:migrate
Then deploy to Heroku and run the migration there too:
git add . git commit -m "Add Active Storage" git push heroku main heroku run rails db:migrate
Associate Files with Your Model
If you're saving files to a model (like Project), add this to your model file (app/models/project.rb):
# For single file uploads has_one_attached :uploaded_file # For multiple file uploads (if needed) # has_many_attached :uploaded_files
3. Update Your Controller to Handle File Uploads
In your StaticPagesController (or whichever controller handles the form submission), add a strong parameter that permits the file field, and save it to your model.
Example controller action:
def submit_project @project = Project.new(project_params) if @project.save flash[:success] = "Form submitted with file!" redirect_to project_path(@project) else render :project end end private def project_params # Permit your existing form fields + the file field params.require(:project).permit(:title, :description, :uploaded_file) end
(Adjust the permitted fields to match your actual form inputs.)
4. Optional: Add File Validation
If you want to enforce rules (like file size or type—even though you said "any format," this is useful for sanity checks), add validations to your model:
class Project < ApplicationRecord has_one_attached :uploaded_file validates :uploaded_file, presence: true # Optional: Limit file size to 10MB validate :file_size_validation private def file_size_validation if uploaded_file.attached? && uploaded_file.byte_size > 10.megabytes errors.add(:uploaded_file, "must be less than 10MB") end end end
5. Configure Heroku for Persistent File Storage
Heroku uses an ephemeral filesystem—meaning files uploaded directly to the server will disappear after a deploy or restart. So you need to connect Active Storage to a cloud storage service like AWS S3 or Cloudinary. Here's the S3 setup:
Add the AWS SDK Gem
Add this to your Gemfile:
gem "aws-sdk-s3", require: false
Run bundle install, commit, and push to Heroku.
Configure Active Storage
Update config/storage.yml to include your S3 setup:
amazon: service: S3 access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> region: us-east-1 # Or your preferred region bucket: your-bucket-name # Replace with your S3 bucket name
Then set your Rails environment to use S3 in config/environments/production.rb:
config.active_storage.service = :amazon
Set Heroku Environment Variables
In your terminal, run these commands (replace with your actual AWS credentials):
heroku config:set AWS_ACCESS_KEY_ID=your-access-key heroku config:set AWS_SECRET_ACCESS_KEY=your-secret-key heroku config:set AWS_BUCKET=your-bucket-name
6. Test the Flow
- Locally: Start your Rails server, navigate to the project page, select a file, submit the form. Check if the file is attached to the
Projectrecord (you can use the Rails console:Project.last.uploaded_file.attached?). - On Heroku: Deploy your changes, test the upload, and verify the file is stored in your S3 bucket.
Bonus: Display Uploaded Files in Views
If you want to show a link to the uploaded file later, add this to your view:
<% if @project.uploaded_file.attached? %> <p>Uploaded File: <%= link_to @project.uploaded_file.filename, rails_blob_path(@project.uploaded_file, disposition: "attachment") %></p> <% end %>
内容的提问来源于stack exchange,提问作者ImmaNoob

