0

我想current_user在我的模型中使用 Devise 的助手,这样我就可以ShopDress模型中使用before_save.

这不起作用:

# Dress model
before_save :set_currency

def set_currency
  self.currency = current_user.shop.currency
end

它确实在控制器中工作:

def create
  @dress = current_user.shop.dresses.create(params[:dress])
  @dress.update_column(:currency, current_user.shop.currency)
end

但它似乎效率低下,因为它会做一个UPDATEafter COMMIT。StackOverflow 上的其他用户说不current_user应该在模型中使用。有没有其他方法可以current_user在模型中访问?

4

3 回答 3

1

一种方法是将用户作为参数传递给模型方法,而不使用 before_save 回调

# Dress model

def set_currency(user)
  self.currency = user.shop.currency
end

另一种方法是专门设置货币。由于货币是 Dress' 字段,您可以使用当前用户货币在表单上放置一个隐藏字段,该字段将作为参数传递给您的创建操作,并为您透明地保存。

如何实现它:

  # At your Dress form, in your View
  <%= f.hidden_field :currency, :value => @user.shop.currency %>

  # At your controller
  def create
      @user = current_user
  end

像这样,您无需做任何事情来保存货币。它将传递参数以创建连衣裙,您只需确保它currency是一个 ActiveRecord 字段。

通常,将这种关于特定时间应用程序状态的知识附加到模型是不好的。如果您发现自己处于绝对确定自己需要这种行为的情况下,请停下来问问自己这是否真的有意义。

在这个例子中,我真的觉得(不知道你的应用程序,有)货币应该是表单中的隐藏字段,因为它是你的模型必须存在的东西,它确实是一个字段,因此它使感觉要与模型的参数一起传递。

最好的祝福

于 2012-12-18T12:12:32.850 回答
1

在控制器中使用 .build 而不是 .create 将值设置为 Dress 模型的货币属性。

def create
    @dress = current_user.shop.dresses.build(params[:dress])
    @dress.currency = current_user.shop.currency
    if @dress.save
       .....
    else
       .....
    end
  end
于 2012-12-18T12:17:14.570 回答
1

我建议只处理在控制器中设置它们,但是......

如果您不介意稍微违反 MVC,可以使用以下方法:

# application_controller.rb
before_filter :set_current
def set_current
  User.current = current_user
end

# app/models/user.rb
cattr_accessor :current

# app/models/dress.rb
before_save :set_currency
def set_currency
  self.currency = User.current.shop.currency
end
于 2012-12-18T16:11:58.467 回答