无法保存form_for一个控制器在视图partial,rails 4中

时间:2016-06-18 23:27:59

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

之前有人问过这个问题,但我找不到任何适用的东西。我要做的是在SettingsController的修改视图中为UsersController呈现修改表单。我是RoR的新手,所以我甚至不确定我做错了什么。

This问题似乎最接近,但是当我在@setting = Setting.new控制器中初始化Users时,我会得到一个Settings表单,而不会为迁移中的新用户设置默认值。但是如果我初始化@setting = Setting.editSetting.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

如何获得正确的默认设置,以便正确保存表单?

2 个答案:

答案 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