我已经(小时)在Rails中遇到关联问题。我发现了很多类似的问题,但我不能申请我的案子:
城市班级:
person.firstName
用户班级:
class City < ApplicationRecord
has_many :users
end
用户控制器:
class User < ApplicationRecord
belongs_to :city
validates :name, presence: true, length: { maximum: 80 }
validates :city_id, presence: true
end
用户查看:
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
迁移:
<%= 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
来自控制台和浏览器的消息:
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
嗯,问题是,用户模型中的属性不是FK,它们是User.save方法接受的,而像citys_id这样的FK属性则不是。然后它在浏览器中给出了错误消息,说“验证失败的城市必须存在”。
由于
答案 0 :(得分:69)
尝试以下方法:
belongs_to :city, optional: true
根据new docs:
4.1.2.11:可选
如果将:optional选项设置为true,则表示存在 相关对象将不会被验证。 默认情况下,此选项已设置 为假。
答案 1 :(得分:8)
这有点晚了但是在rails 5中默认情况下如何关闭:
<强> 配置/初始化/ new_framework_defaults.rb 强>
Rails.application.config.active_record.belongs_to_required_by_default = false
如果您不想将optional: true
添加到所有belongs_to
。
我希望这有帮助!
答案 2 :(得分:4)
您需要在belongs_to关系语句的末尾添加以下内容:
optional: true
可以在全局级别设置它,以便它与旧版本的rails一样工作,但我建议花时间手动将其添加到真正需要它的关系中,因为这样会减少未来的痛苦。
答案 3 :(得分:2)
我找到了问题的解决方案&#34;验证失败:班级必须存在&#34;它比使用更好:
belongs_to :city, optional: true
4.1.2.11:可选
如果将:optional选项设置为true,则不会验证相关对象的存在。默认情况下,此选项设置为false。
因为您仍然在应用程序级别进行验证。我解决了在create方法中自己进行验证并更改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
我没有测试过这段代码,但它可以在另一个项目中使用。我希望它可以帮助别人!
答案 4 :(得分:2)
Rails 5
如果您与belongs_to
之间存在:parent
关系,则必须传递现有父对象或创建新对象,然后分配给子对象。
答案 5 :(得分:1)
belongs_to :city, required: false
答案 6 :(得分:0)
Rails.application.config.active_record.belongs_to_required_by_default = false
这有效,因为默认情况下Rails 5具有true 要禁用您,请进入“初始化器”,然后单击“ New_frame-work”,然后将true设置为false
答案 7 :(得分:0)
params.require(:user).permit(:name, :citys_id)
这是一个错误,不是吗? (city s _id与city_id)