Ruby on rails Can';t在局部视图中保存一个控制器的表单_,rails 4
这个问题以前被问过很多次,但我找不到任何合适的答案。我试图做的是在Ruby on rails Can';t在局部视图中保存一个控制器的表单_,rails 4,ruby-on-rails,ruby,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby,Ruby On Rails 4,Activerecord,这个问题以前被问过很多次,但我找不到任何合适的答案。我试图做的是在userscoontroller的编辑视图中呈现settingscoontroller的编辑表单。我是RoR的新手,所以我甚至不知道自己做错了什么 问题似乎最接近,但当我在用户控制器中初始化@setting=setting.new时,我会得到一个设置表单,其中没有为迁移中的新用户设置的默认值。但是如果我初始化@setting=setting.edit或setting.update,我会得到一个未定义的方法或错误的参数数错误 保存设
userscoontroller
的编辑视图中呈现settingscoontroller
的编辑表单。我是RoR的新手,所以我甚至不知道自己做错了什么
问题似乎最接近,但当我在用户
控制器中初始化@setting=setting.new
时,我会得到一个设置
表单,其中没有为迁移中的新用户设置的默认值。但是如果我初始化@setting=setting.edit
或setting.update
,我会得到一个未定义的方法或错误的参数数错误
保存设置.new
表单时,会抛出以下错误:
在“正确的用户”中的设置控制器:app/controllers/settings\u controller.rb:43中,按id查找\u的未定义方法
当我检查数据库时,在创建用户时,设置记录被正确创建,但在保存表单时,设置记录不会更新
setting.rb:
class Setting < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
end
ETA:设置迁移:
class CreateSettings < ActiveRecord::Migration
def change
create_table :settings do |t|
t.string :reading_theme, default: => "flatly"
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
class CreateSettings“平坦”
t、 参考:用户,索引:true,外键:true
t、 时间戳null:false
结束
结束
结束
如何获得正确的默认值,以便正确保存表单?对于Ruby中的模型类(设置),迁移中包含的字段默认值都是“未知”的。Ruby(或者说Rails ActiveRecord)在创建模型对象时不会从表定义中读取默认值。这会导致双重人格问题,就像你在这里看到的那样 您需要做的是在适当的地方将相关的默认值添加到Ruby代码中。例如,在设置控制器中,可以进行以下更改:
def new
@setting = Setting.new
# Set any defaults that will be visible to the user on the form
@setting.reading_theme = "flatly"
# The form will allow the user to choose their own values, based on the defaults
end
def create
@setting = current_user.settings.build(setting_params)
# Set any defaults that will NOT be visible to the user
@setting.save
end
这使您能够区分用户可见的默认值和不可见的默认值
请注意,在创建模型对象时,您还可以选择建立默认值,但在某些情况下,这可能更复杂,在实际使用中似乎不太常见。如果这更适合您的需要,那么有一个很好的答案。在has\u one关系中不能使用find\u by\u id @setting=当前用户。setting.按\u id查找\u(参数[:id])
Just@setting=current_user。setting请包括您提到的迁移,特别是默认值。这将为您的项目提供一个合适的答案。@MichaelGaskill,刚刚添加了它。我刚刚在
new
操作中将其添加到我的答案中。谢谢!因此,在这个答案和@Dennicastro的答案之间,表单正在呈现,并且在保存时不再抛出错误,但它也不会保存到数据库中。我想我没有正确理解def new和def create需要更改的位置——我在UsersController中假设过?因为如果我在SettingsController中更改它们,我会继续得到一个零参数错误。除了将它们添加到UsersController似乎会创建一个空表单,并且不会保存任何内容。我觉得我缺少了一些简单的东西。@JimHogan我更新了我的答案,说应该对设置控制器进行更改。请注意,Dennicastro的回答不应应用于新建
或创建
操作,因为这是专门用于编辑
或显示
操作的方法。正如“nil argument error”所证明的那样,您的代码可能还存在其他问题,需要解决这些问题才能获得完整的解决方案,并且您必须使用相关的错误详细信息(整个操作日志,包括堆栈跟踪)来更新您的问题,以便能够解决这些问题。
class SettingsController < ApplicationController
before_action :logged_in_user, only: [:create, :edit, :update, :show, :index]
before_action :correct_user, only: [:create, :edit, :update, :show, :index]
def index
@settings = Setting
end
def show
@setting = User.find(params[:id]).setting
end
def new
@setting = Setting.new
end
def edit
@setting = Setting.find(params[:id])
end
def create
@setting = current_user.settings.build(setting_params)
@setting.save
end
def update
@setting = Setting.find(params[:id])
if @setting.update_attributes(post_params)
flash[:success] = "Settings updated!"
redirect_to request.referrer
else
render 'edit'
end
end
private
def setting_params
params.require(:setting).permit(:reading_theme)
end
def correct_user
@setting = current_user.setting.find_by_id(params[:id]) ##the line which throws an error when the form is saved
redirect_to root_url if @setting.nil?
end
end
<%= form_for(@setting) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= radio_button_tag(:reading_theme, "flatly") %>
<%= label_tag(:reading_theme_flatly, "Light (Default)") %>
</div>
<div class="field">
<%= radio_button_tag(:reading_theme, "darkly") %>
<%= label_tag(:reading_theme_darkly, "Dark") %>
</div>
<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>
resources :users do
member do
get :following, :followers
end
end
resources :settings, only: [:new, :create, :edit, :update]
...
class CreateSettings < ActiveRecord::Migration
def change
create_table :settings do |t|
t.string :reading_theme, default: => "flatly"
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
def new
@setting = Setting.new
# Set any defaults that will be visible to the user on the form
@setting.reading_theme = "flatly"
# The form will allow the user to choose their own values, based on the defaults
end
def create
@setting = current_user.settings.build(setting_params)
# Set any defaults that will NOT be visible to the user
@setting.save
end