如何在before_filter中使用request.env?

时间:2012-10-05 12:06:15

标签: ruby-on-rails before-filter before-save

我想在保存之前检查一些字段并将其更改为默认的浏览器语言。

我想使用before_save过滤器:

def update
 @website = Website.find(params[:id])
  if @website.language == "Automatic (by user's browser language)"
   @website.language = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
 end
respond_to do |format|
  if @website.update_attributes(params[:website])
    format.html { redirect_to @website, 
      notice: 'Note: code has been updated. Please replace the code you have on your website with the code below. Only then changes will take effect.'}
    format.js
   end
  end
end

我需要检查:

  if @website.language == "Automatic (by user's browser language)"
    @website.language = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
 end

它适用于创建操作,但不适用于更新。

我该怎么做?

4 个答案:

答案 0 :(得分:1)

在模型中使用保存之前,模型中通常不提供请求。

但是,如果您真的想在那里进行,请查看:http://m.onkey.org/how-to-access-session-cookies-params-request-in-model了解有关如何操作的详细信息。

- 编辑 -

有几种方法可以做到。

首先想到的是你将attr_accessor :request_language添加到模型中,然后将request.env['HTTP_ACCEPT_LANGUAGE']从控制器传递给模型:

if @website.update_attributes(params[:website])
  @website.request_language = request.env['HTTP_ACCEPT_LANGUAGE']
  # ...

现在你可以像以前那样继续进行一些修改:

def auto_language
    if self.language == "Automatic (by user's browser language)"
         self.language = full_language(self.request_language.scan(/^[a-z]{2}/).first)
    end
 end

我能想到的第二种方法是在控制器中使用前/后过滤器来影响params,然后再将它们传递给模型。

...

答案 1 :(得分:1)

如果您想在创建操作后更新某些内容但不更新操作,请参阅示例

# write in your model
after_create :xyz
def xyz
 ...
 ...
end

以上方法 xyz 在创建操作后调用。当更新呼叫时,它将不会呼叫。

答案 2 :(得分:0)

request对象在模型中不可用。您应该在控制器层上进行这些调整。

def action
    if @model.language == "Automatic (by user's browser language)"
         @model.language = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
    end
    if @model.save
        ... 
    else
        ...
    end
end

private

def full_language
  ...
end

答案 3 :(得分:0)

您需要更改:language哈希中params的值,因为这是您最终传递给@website.update_attributes的内容。我还建议将该条件移动到模型层中,以使您的控制器代码更具可读性:

# app/controllers/websites_controller.rb
def update
  @website = Website.find(params[:id])
  if @website.language_automatic?
    params[:website][:language] = full_language(request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first)
  end
  respond_to do |format|
    if @website.update_attributes(params[:website])
      format.html { redirect_to @website, 
        notice: 'Note: code has been updated. Please replace the code you have on your website with the code below. Only then changes will take effect.'}
      format.js
    end
  end
end

# app/models/website.rb
def language_automatic?
  language == "Automatic (by user's browser language)"
end