【问题标题】:What does first.user = current_user mean/do and why is it working?first.user = current_user 是什么意思/做什么,为什么它有效?
【发布时间】:2011-09-28 12:38:59
【问题描述】:

首先,我有 3 个模型:

Location has_many :products
User has_many :products
Products belongs_to :user, :location

现在我有一个嵌套表单:

<%= nested_form_for @location do |f| %>
<%= f.error_messages %>
.............
<% f.fields_for :products do |product| %>

我试图找到让我的 current_user 关联正常工作的正确方法,但突然间,我在这个问题中找到了正确答案,Nil foreign key in a nested form

我把这段简单的代码放在我的控制器中,它最终把我的产品给了当前的user_id:

@location.products.first.user = current_user

满 -

def create
    @location = Location.new(params[:location])
    @location.products.first.user = current_user
end

我的最终目标已经完成。用户在特定位置创建了自己的产品。我唯一不明白的是为什么first.user = current_user 可以工作,而像location = @location.current_user.products.build 这样简单的东西却不行。有人可以给我一个很好的解释,说明这里发生了什么以及前者的含义吗?这是可以拥有的还是他们更安全/更好的方式?

谢谢你,我很感激。

【问题讨论】:

    标签: ruby-on-rails ruby devise nested-forms


    【解决方案1】:

    定义current_user的最简单方法是

    class ApplicationController < ActionController::Base  
      protect_from_forgery  
      helper_method :current_user  
    
    private  
      def current_user  
        @current_user ||= User.find(session[:user_id]) if session[:user_id]  
      end  
    end 
    

    所以current_userApplicationController 类中定义 每当你想做的时候

    @location = Location.new(params[:location])
    @location.current_user 
    

    您正在尝试将其他类中定义的方法调用为Location 实例的方法

    【讨论】:

    • 能否详细说明一下?
    【解决方案2】:

    在此声明中

    @location.products.first.user = current_user
    

    Rails 默认将 current_user 的 id 分配到左侧。通过对to_param 的内部调用使之成为可能。您甚至可以覆盖该方法以返回其他内容,甚至是随机内容,但这不会有帮助:)

    关于@location.current_user.products.build, 这将不起作用,因为位置和用户不相关,如果要使其工作,可以通过在新方法中构建产品并将当前用户 ID 作为参数传递给方法来实现。

    def new
      @location = Location.new
      @location.products.build
      respond_to do|format|
        format.html
      end
    end
    

    更新:我接受tumtu的评论,不建议将用户ID作为隐藏元素。

    【讨论】:

    • 在视图中使用user_id是严重的安全漏洞,应该将user_id添加到attr_protected列表中。
    • @Felix 你放置的 def 新方法只是给了我已经添加的价格字段,我正在弄清楚如何做,我感谢你,但它仍然没有分配正确的用户 ID。
    • 是的,确实如此...它只是构建了一个属于该位置的空白产品...为了设置它,您可以像以前一样设置它,也可以创建一个执行的 before_filter仅适用于分配 user_id 的创建操作。如果您要使用后一种情况,则无需在创建操作中使用新方法。您可以直接将参数分配给@location。如果此注释不是清楚,我会在几分钟内更新我的答案...:)
    猜你喜欢
    • 2020-04-13
    • 2011-07-12
    • 2011-04-21
    • 2011-12-27
    • 2017-09-12
    • 2013-10-31
    • 2012-03-05
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多