9
votes

Rails: impossible de résoudre l'image en URL: to_model déléguée à la pièce jointe, mais la pièce jointe est nulle Rails 5.2

J'ai le formulaire suivant:

  def identity_params
    params.permit(:email_confirmation, :password, :password_confirmation, :avatar).to_h.symbolize_keys.tap do |params|
      params[:email] = params[:email_confirmation]
    end 
  end 

Il est appelé sur ma page edit :

<h1>Upload Avatar</h1>
  <%= image_tag(@user.avatar) %>
  <%= render 'form', user: @user %>
<hr>

J'obtiens l'erreur dans le titre mais je ne sais pas pourquoi l'avatar n'est pas attaché au modèle user . J'ai toutes les conditions requises pour active_storage .

has_one_attached: avatar dans le modèle utilisateur .

Dans le contrôleur utilisateur :

<%= form_with(model: user, local: true) do |form| %>
  <% if user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.file_field :avatar %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

J'ai également toutes les migrations nécessaires. Suis-je absent de la logique d'attachement de l'avatar?


0 commentaires

4 Réponses :


2
votes

Il semble qu'il vous manque une configuration (car vous ne la mentionnez pas):

Vous devez déclarer les services Active Storage dans config/storage.yml

Exemple de docs:

# Store files locally.
config.active_storage.service = :local

et vous devez indiquer à Active Storage quel service utiliser en définissant Rails.application.config.active_storage.service

Étant donné que chaque environnement utilisera probablement un service différent, il est recommandé de le faire pour chaque environnement. Pour utiliser le service de disque de l'exemple précédent dans l'environnement de développement, vous devez ajouter ce qui suit à config / environnements / development.rb :

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""


2 commentaires

J'avais tout si c'était mis en place. Désolé j'ai oublié de le mentionner.


Je mets à jour une application existante. Il n'y a pas de telle configuration ici. J'ai trouvé cette réponse utile.



24
votes

Vous pouvez obtenir le message d'erreur "Impossible de résoudre l'image en URL: to_model délégué à la pièce jointe, mais la pièce jointe est nulle" si vous essayez d'afficher dans votre vue une pièce jointe qui n'existe pas :

<%= image_tag(@user.avatar) if @user.avatar.attached? %>

pour éviter les erreurs, vous devez faire ceci:

<%= image_tag(@user.avatar) %>


5 commentaires

Merci pour votre réponse. Je voulais dire que je ne sais pas pourquoi il n'enregistre pas l'avatar dans la base de données.


Le problème n'était pas d'avoir user.avatar.attach (params ['user'] ['avatar']) dans le contrôleur .


Quel type de stockage utilisez-vous? local ou cloud? le stockage dans le cloud peut rencontrer des problèmes avec CORS . Avez-vous des erreurs dans la console de votre navigateur?


@ A.J dans quel contrôleur? dans le contrôleur des utilisateurs?


BTW github.com/rails/rails/issues/35613 Je suis confronté à ce problème au hasard dans mon développement, même si l'enregistrement était correctement attaché à un fichier, et je peux voir des insertions effectuées dans des tables de stockage actives, mais il perd en quelque sorte la pièce jointe plus tard. Cela arrive à certains enregistrements aléatoires, pas à chaque enregistrement.



1
votes

J'étais également confronté à la même erreur en raison de l'erreur stupide. En fait, j'ai ajouté de l'espace supplémentaire à la clé locale: . Assurez-vous donc de suivre l'indentation appropriée. Et ne devrait pas manquer la configuration. Vous devez déclarer les services Active Storage dans config / storage.yml de la manière suivante.

config.active_storage.service = :local #environment/development.rb
config.active_storage.service = :amazon ##environment/production.rb
config.active_storage.service = :test #environment/test.rb

Assurez-vous que dans les paramètres environment / development.rb, environment / production.rb et environment / test.rb vous ont ajouté la ligne de code suivante

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  bucket: ""
  region: "" # e.g. 'us-east-1'


0 commentaires

1
votes

Soultion si votre identifiant de modèle utilisateur est UUID

Vous devez modifier un peu la migration ActiveStorage en ajoutant type:: uuid à Migration ActiveStorage par champ enregistrement

create_table :active_storage_attachments do |t|
  t.string     :name,     null: false
  t.references :record,   null: false, polymorphic: true, index: false, type: :uuid
  ...

référence https://edgeguides.rubyonrails.org/active_storage_overview.html#setup


0 commentaires