【问题标题】:Update attributes separately in Rails在 Rails 中单独更新属性
【发布时间】:2014-02-28 08:08:41
【问题描述】:

尝试将 2 个属性更新为 User 模型,这是我在 Users 控制器中的当前代码:

def update
@user = User.find(params[:id])
if @user.update_attributes(songkickID: params[:user][:songkickID], jamID: params[:user][:jamID])

  redirect_to @user
else
  redirect_to @user
end
end

将 Songkick ID 和 Jam ID 输入到 2 个不同的字段中。但是,使用当前代码,如果我尝试自行更新 Jam ID,它会更新该属性,但随后会重定向到用户页面(如预期的那样),其中 Songkick ID 现在为零。再次输入 Songkick ID 后,Jam ID 变为 nil。我想这是因为它们都是控制器中相同 if 语句的一部分?

我尝试为 jamID 参数使用 elsif,但它似乎根本无法识别(即不会为用户更新该属性)。也尝试过||条件运算符。

编辑:这是两种不同的形式:

<%= form_for(@user) do |f| %>

  <%= f.text_field :jamID, :id=>"jamURL" %>


    <%= f.submit "Jam ID", :onclick => "changeImg()", id: "saveJam" %>

<% end %>

<%= form_for(@user) do |f| %>

  <%= f.text_field :songkickID %>

  <%= f.submit "Songkick ID", :type => :image, :src => image_path("songkicklogo.png"), id: "skLogo" %>
<% end %>


我尝试将代码修改为 update_column,但我得到的参数数量错误(1 比 2)。

编辑 2:按照 Hartl 的 Rails 教程中的布局,我尝试这样做来定义强参数:

private

def user_params
  params.require(:user).permit(:songkickID, :jamID)
end

但我仍然收到禁止属性错误?

编辑 3:以下代码通过,但我担心它不符合 Rails 4 强参数:

控制器:

class UsersController < ApplicationController
def show
    @user = User.find(params[:id])
end

def edit
    @user = User.find(params[:id])
end



def user_params
  params.require(:user).permit(:songkickID, :jamID)
end

def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)

  redirect_to @user
else
  redirect_to @user
end


end
end

如果我将更新移动到更新方法下方,我会收到 user_params 的未定义变量/方法错误,并且我无法将其设为私有。

【问题讨论】:

  • 我想我不完全明白你在问什么。是否要更新这两个属性?你能告诉我们设置这些值的表单吗?
  • 你有什么理由要创建两个不同的表单吗?因为如果你想同时更新这两个属性,它们应该在同一个
  • 两种不同的形式,因为我不希望它们同时更新(songkick ID 是一次性的,Jam ID 会经常更新)。

标签: ruby-on-rails params update-attributes


【解决方案1】:

那么 - 为什么要在 update_attributes 中明确命名属性?

您应该能够使用以下内容:

@user.update_attributes(params[:user])

请记住,如果您已正确命名表单字段,则 params[:user] 是一个哈希值,其中已经包含您想要的键(:songkickID 等)

现在 - 您将获得两件事之一,然后您将其传递给 update_attributes:

{:songkickID => someID}
{:jamID => someOtherID}

这将正确更新您的用户,并且只更改通过的用户。

您之前代码的问题在于您传递给更新属性的内容是:

{:songkickID => someID, :jamID => nil}
{:songkickID => nil, :jamID => someOtherID}

这是故意用你传递的 nil 覆盖另一个 id。

来自 OP 的编辑:谢谢,这是我的最终控制器代码:

class UsersController < ApplicationController
def show
    @user = User.find(params[:id])
end

def edit
    @user = User.find(params[:id])
end


def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)

  redirect_to @user
else
  redirect_to @user
end   
end


private


def user_params
  params.require(:user).permit(:songkickID, :jamID)
end
end

【讨论】:

  • 根据您之前的评论,这里有两种不同的形式: "jamURL" %> "changeImg()", id: "saveJam" %> 和 :image, :src => image_path("songkicklogo.png"), id: "skLogo" %>
    我尝试将代码修改为 update_column,但我得到的参数数量错误(1 比 2)。
  • 这在评论中效果不佳-您可以将其放入您的问题中以便格式化
  • 对 - 所以我明白你对各个字段的意思。所以我上面的代码应该可以工作 - 因为这意味着你并没有真正为 other 字段传递一个 nil (你没有更新)。上面的代码只会传递正在改变的字段。
  • 现在我得到一个禁止属性错误,这是因为强参数吗?尝试卡尔建议的答案时也是如此。
  • 你说得对,太早忘记贴一个“结束”了,会更新答案:)
【解决方案2】:

最后一种情况:

    def update
      if params[:user][:songkickID]
        received_param = { songkickID: params[:user][:songkickID] }
      elsif params[:user][:jamID]
        received_param = { jamID: params[:user][:jamID] }
      end

      @user.update_attributes(received_param)
      redirect_to @user
    end

注意:我删除了最后一个条件,因为它没有用

【讨论】:

  • 这个有语法错误,只是使用了我在 Taryn 的答案中更新的代码,无论如何谢谢。
  • @Rafael - 可行,但同样 - 在这种情况下它有点麻烦并且没有必要。由于 OP 设置表单的方式 - params[:user] 也可以工作。
猜你喜欢
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
相关资源
最近更新 更多