之前有人问过这个问题,但我找不到任何适用的东西。我要做的是在SettingsController
的修改视图中为UsersController
呈现修改表单。我是RoR的新手,所以我甚至不确定我做错了什么。
This问题似乎最接近,但是当我在@setting = Setting.new
控制器中初始化Users
时,我会得到一个Settings
表单,而不会为迁移中的新用户设置默认值。但是如果我初始化@setting = Setting.edit
或Setting.update
,我会得到一个未定义的方法或错误的参数数量错误。
保存Setting.new
表单后,会抛出此错误:
SettingsController中的find_by_id的未定义方法:app / controllers / settings_controller.rb:43:在`correct_user'。
检查数据库时,创建用户时正确创建了设置记录,但保存表单时未更新设置记录。
setting.rb:
class Setting < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
end
user.rb:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_one :setting, dependent: :destroy
after_create :create_setting
end
UsersController:
class UsersController < ApplicationController
before_action :logged_in_user, only: [:edit, :update, :index, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def new
@user = User.new
end
def edit
@user = User.find(params[:id])
@setting = Setting.update
end
def update
@user = User.find(params[:id])
@setting = Setting.update
if @user.update_attributes(user_params)
flash[:success] = "Profile updated!"
redirect_to @user
else
render 'edit'
end
end
def settings
@title = "Settings"
@setting = Setting.find_by_user_id(params[:user_id])
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Confirms the correct user.
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
SettingsController:
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 %>
routes.rb中:
resources :users do
member do
get :following, :followers
end
end
resources :settings, only: [:new, :create, :edit, :update]
...
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
如何获得正确的默认设置,以便正确保存表单?
答案 0 :(得分:1)
您为迁移中的字段包含的任何默认值都将是&#34;未知&#34;到Ruby中的模型类(Setting)。在创建模型对象时,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
这使您能够区分用户可见的默认值和非默认值。
请注意,您还可以在创建模型对象时选择建立默认值,但在某些情况下这可能会更复杂,并且在实际使用中似乎更不常见。在How to initialize an ActiveRecord with values in Rails?中有一个SO答案,以防这更符合您的需求。
答案 1 :(得分:0)
不能在has_one关系中使用find_by_id
@setting = current_user.setting.find_by_id(params [:id])
只是@setting = current_user.setting