我正在使用Rails 3.2.17
尝试访问模型中的两个虚拟属性(expiration_amount
& expiration_format
)但我尝试过的任何内容都无法访问它们
其他所有内容似乎都正确更新,但在我的日志中,虚拟属性总是空白。
编辑我按照建议将:expiration_amount
:expiration_format
添加到attr_accessible
,但它仍然无效。他们都是空白。我注意到的一件事是记录器调用是在它击中数据库后发生的。 before_update
不是正确的过滤器吗?
编辑2 Devise
是否可以阻止访问虚拟属性?
编辑3 我刚决定从控制器(它正在工作)开始,虽然我仍然很好奇为什么我无法访问这些虚拟属性该模型。
工作控制器操作(更新方法)
@user.set_expiration(params[:expiration_amount].to_i, params[:expiration_format])
工作模式方法
def set_expiration(amount, format)
if defined?(amount) && defined?(format)
case format
when "hours"
self.expiration = amount.hours.from_now
when "days"
self.expiration = amount.days.from_now
when "weeks"
self.expiration = amount.weeks.from_now
else
self.expiration = amount.hours.from_now
end
end
end
---原始代码---
User.rb
class User < ActiveRecord::Base
attr_accessible :email,
:password,
:password_confirmation,
:remember_me,
:first_name,
:last_name,
:company,
:phone,
:expiration,
:expiration_amount,
:expiration_format
attr_accessor :expiration_amount,
:expiration_format
before_update :set_expiration
def set_expiration
logger.debug "DEBUG - expiration_amount: #{expiration_amount}"
logger.debug "DEBUG - expiration_format: #{expiration_format}"
if expiration_amount && expiration_format
case expiration_format
when "hours"
self.expiration = expiration_amount.hours.from_now
when "days"
self.expiration = expiration_amount.days.from_now
when "weeks"
self.expiration = expiration_amount.weeks.from_now
else
self.expiration = expiration_amount.hours.from_now
end
end
end
end
形式
= form_for(resource, :as => resource_name, :url => admins_user_update_path(resource), :html => { :method => :put }) do |f|
= devise_error_messages!
%fieldset{id: "edit-user-account"}
%legend
Set User Access
.field.required
%label
"Allow access for "
= select_tag "expiration_amount", options_for_select(expiration_amount, 3)
= select_tag "expiration_format", options_for_select(expiration_format, "days")
%span.instructions
From Now
.field
= f.submit "Grant Access"
日志
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxx=", "expiration_amount"=>"3", "expiration_format"=>"days", "commit"=>"Grant Access", "id"=>"5"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", "5"]]
Admin Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = 1 LIMIT 1
(0.3ms) BEGIN
DEBUG - expiration_amount:
DEBUG - expiration_format:
(0.3ms) COMMIT
Redirected to http://localhost:8080/admins/users
答案 0 :(得分:0)
Rails 3: 也可以将它们放在attr_accessible中。
Rails 4: 确保你允许它们。
答案 1 :(得分:0)
我建议使用rails form helper创建表单:
.field.required
= form_for @user do |f|
= f.label :expiration, "Allow access for "
= f.select "expiration_amount", options_for_select(expiration_amount, 3)
= f.select "expiration_format", options_for_select(expiration_format, "days")
%span.instructions
From Now
然后在你的控制器中:
@user = User.find(params[:id])
@user.update_attributes(params[:user])
答案 2 :(得分:0)
我终于弄明白了问题是什么!因为我在select_tags
使用了叮咬,所以没有正确命名它们,所以:
= select_tag "expiration_amount", options_for_select(expiration_amount, 3)
= select_tag "expiration_format", options_for_select(expiration_format, "days")
呈现为:
<select id="expiration_amount" name="expiration_amount">
<select id="expiration_format" name="expiration_format">
但他们需要让模特选择它们是:
= f.select :expiration_amount, options_for_select(expiration_amount, 3)
= f.select :expiration_format, options_for_select(expiration_format, "days")
<select id="user_expiration_amount" name="user[expiration_amount]">
<select id="user_expiration_format" name="user[expiration_format]">
之后我能够在模型中完成所有操作而不是控制器。
模型方法
before_update :set_expiration
def set_expiration
logger.debug "DEBUG @ User - expiration_amount: #{expiration_amount}"
logger.debug "DEBUG @ User - expiration_format: #{expiration_format}"
if defined?(expiration_amount) && defined?(expiration_format)
amount = expiration_amount.to_i
case expiration_format
when "hours"
self.expiration = amount.hours.from_now
when "days"
self.expiration = amount.days.from_now
when "weeks"
self.expiration = amount.weeks.from_now
else
self.expiration = 0.hours.from_now
end
end
end