如何实现用户只能编辑记录中的某些字段?
例如:
用户可以在系统上注册并选择并指定用户名,密码等。但注册用户只能编辑他的姓名,电子邮件和密码,而不能编辑他的用户名。
我有一个部分_form,用于新功能和编辑功能。 部分看起来像这样:
<% form_for @user do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :gruebl_employee_id %><br />
<%= f.collection_select(:firma_employee_id, FirmaEmployee.find(:all).sort_by{|p| p.lastname.downcase},:id,:full_name, { :include_blank => "---keine Mitarbeiter---", :prompt => "---Bitte auswählen---"}, { :style => "width: 332px;"}) %>
</p>
<%= observe_field(:user_firma_employee_id,
:frequency => 0.25,
:url => { :action => :retrieveinfo },
:with => "'id='+value") %>
<p>
<%= f.label :username %><br />
<%= f.text_field :username %>
</p>
<p>
<%= f.label :admin, "Administrator ?" %><br />
<%= f.check_box :admin %>
</p>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
<p><%= f.submit %></p>
<%end%>
我要做的是阻止用户更改员工和用户名属性。
提前致谢。
答案 0 :(得分:9)
在几个地方照顾好这个。
首先,在User模型中使用attr_accessible,仅包含您希望用户编辑的那些:
attr_accessible :name, :email, :password, :password_confirmation #...
然后在形式partial中,仅在显示注册表单时显示用户名字段:
<% if @user.new_record? %> <%= f.text_field :username %> <% end %>
最后,在创建操作中,手动设置用户名字段,因为它现在位于attr_accessible列表中,您无法批量分配它:
@user = User.new(params[:user]) @user.username = params[:user][:username]
请注意,如果可以通过批量分配设置用户名,即使您在表单中禁用了用户名字段,它仍然可以修改(很容易在客户端更改表单中的字段值) 。这就是我们必须使用attr_accessible进行预检的原因。
编辑:注意到你的部分,最好将admin字段保护为用户名,否则用户可以通过更改客户端的字段值将自己设置为admin。
答案 1 :(得分:0)
我可以看到你有两种方法可以做到这一点。
1 - 使用html支持使文本框只读。所以在你的情况下,user_name文本框将是这样的
<input type="text" name="user_name" value="<User Name>" readonly="readonly" />
2 - 但我更喜欢在rails应用程序中创建一个只读文本框,帮助者可以在需要时调用它
所以示例是
在我的应用程序助手
中module ApplicationHelper
def read_only_text_field(object_name, method, options = {})
text_field(object_name, method, :disabled => true)
end
end
在我看来我有
<%= read_only_text_field :user, :user_name %>
我认为它更干旱/铁路。
**重要 - 并确保在保存等时从控制器中计算只读值。通过这种方式,即使用户更改这些只读值,您仍然无法解决问题:D
希望这会有所帮助
欢呼声
sameera
答案 2 :(得分:0)
诀窍是将“对象”与标签结合使用,以用于您不想更改的任何内容。以下是您应该如何为用户名编写代码:
<%= f.label(:username, f.object.username) %>
答案 3 :(得分:0)
这是我针对类似问题的相关解决方案-我们有一些字段,希望用户能够设置自己,我们在创建记录时不需要它们,但是我们不希望一旦更改它们就可以对其进行更改已设置。
validate :forbid_changing_some_field, on: :update
def forbid_changing_some_field
return unless some_field_changed?
return if some_field_was.nil?
self.some_field = some_field_was
errors.add(:some_field, 'can not be changed!')
end
让我惊讶的是update_attribute
仍然有效,它绕过了验证。没什么大不了的,因为实际上对记录的更新是批量分配的-但我在测试中对此进行了明确说明。这是一些测试。
describe 'forbids changing some field once set' do
let(:initial_some_field) { 'initial some field value' }
it 'defaults as nil' do
expect(record.some_field).to be nil
end
it 'can be set' do
expect {
record.update_attribute(:some_field, initial_some_field)
}.to change {
record.some_field
}.from(nil).to(initial_some_field)
end
describe 'once it is set' do
before do
record.update_attribute(:some_field, initial_some_field)
end
it 'makes the record invalid if changed' do
record.some_field = 'new value'
expect(record).not_to be_valid
end
it 'does not change in mass update' do
expect {
record.update_attributes(some_field: 'new value')
}.not_to change {
record.some_field
}.from(initial_some_field)
end
it 'DOES change in update_attribute!! (skips validations' do
expect {
record.update_attribute(:some_field, 'other new value')
}.to change {
record.some_field
}.from(initial_some_field).to('other new value')
end
end
end