J'ai eu (heures) des problèmes avec les associations dans Rails. J'ai rencontré beaucoup de problèmes similaires, mais je ne pouvais pas postuler pour mon cas:
Classe de la ville:
class City < ApplicationRecord
has_many :users
end
Classe de l'utilisateur:
class User < ApplicationRecord
belongs_to :city
validates :name, presence: true, length: { maximum: 80 }
validates :city_id, presence: true
end
Contrôleur d'utilisateurs:
def create
Rails.logger.debug user_params.inspect
@user = User.new(user_params)
if @user.save!
flash[:success] = "Works!"
redirect_to '/index'
else
render 'new'
end
end
def user_params
params.require(:user).permit(:name, :citys_id)
end
Vue des utilisateurs:
<%= form_for(:user, url: '/user/new') do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :citys_id, "City" %>
<select name="city">
<% @city.all.each do |t| %>
<option value="<%= t.id %>"><%= t.city %></option>
<% end %>
</select>
end
Émigrer:
class CreateUser < ActiveRecord::Migration[5.0]
def change
create_table :user do |t|
t.string :name, limit: 80, null: false
t.belongs_to :citys, null: false
t.timestamps
end
end
Message de la console et du navigateur:
ActiveRecord::RecordInvalid (Validation failed: City must exist):
Le problème est que les attributs du modèle de l'utilisateur qui ne sont pas FK sont acceptés par la méthode User.save et que les attributs FK tels que citys_id ne le sont pas. Ensuite, il me donne un message d'erreur dans le navigateur disant que "La validation a échoué, la ville doit exister".
Merci
Essayez ce qui suit:
belongs_to :city, optional: true
Selon le nouveaux documents :
4.1.2.11: facultatif
Si vous définissez l'option: optional sur true, la présence de l'objet associé ne sera pas validée. Par défaut, cette option est définie sur false.
Cela arrive un peu tard mais c’est comment désactiver cela par défaut dans Rails 5:
config/initializers/new_framework_defaults.rb
Rails.application.config.active_record.belongs_to_required_by_default = false
Si vous ne voulez pas ajouter optional: true
à tous vos belongs_to
.
J'espère que ça aide!
Vous devez ajouter les éléments suivants à la fin de la déclaration de relation appartenance:
optional: true
Il est possible de définir cette option au niveau global de manière à ce qu'elle fonctionne de la même manière que les anciennes versions de Rails, mais je vous conseillerais de prendre le temps de l'ajouter manuellement aux relations qui en ont réellement besoin, car cela entraînerait moins de difficultés pour l'utilisateur. futur.
Rails 5
Si tu as un belongs_to
Relation avec :parent
vous devez ensuite transmettre un objet parent existant ou en créer un nouveau, puis l’affecter à l’objet enfants.
J'ai trouvé une solution au problème "La validation a échoué: la classe doit exister" et c'est mieux que d'utiliser:
belongs_to :city, optional: true
4.1.2.11: facultatif
Si vous définissez l'option: optional sur true, la présence de l'objet associé ne sera pas validée. Par défaut, cette option est définie sur false.
car vous faites toujours une validation au niveau de l'application. Je résous le problème en faisant ma propre validation dans la méthode create et en changeant la méthode user_params:
def create
@city = City.find(params[:city_id])
Rails.logger.debug user_params.inspect
@user = User.new(user_params)
@user.city_id = @city.id
if @user.save!
flash[:success] = "Works!"
redirect_to '/index'
else
render 'new'
end
end
def user_params
params.require(:user).permit(:name)
end
Je n'ai pas testé ce code, mais cela fonctionne dans un autre projet de mine. J'espère que cela peut aider les autres!
belongs_to :city, required: false