Разрешить пользователю редактировать только некоторые поля в Ruby on Rails - PullRequest
5 голосов
/ 17 февраля 2011

Как мне добиться, чтобы пользователь мог редактировать только некоторые поля из записи?

Например:

Пользователь может зарегистрироваться в системе, выбрать и указать имя пользователя, пароль и т. Д. Но зарегистрированный пользователь может редактировать только свое имя, адрес электронной почты и пароль, но не свое имя пользователя.

У меня есть частичная форма _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%>

То, что я пытаюсь сделать, - это запретить пользователю изменять сотрудника и атрибут имени пользователя.

Заранее спасибо.

Ответы [ 4 ]

9 голосов
/ 17 февраля 2011

Позаботьтесь об этом в нескольких местах.

Во-первых, используйте attr_accessible в модели User, чтобы включить только те, которые вы хотите отредактировать пользователем:

attr_accessible :name, :email, :password, :password_confirmation #...

Затем в частичной форме отображается только поле имени пользователя при отображении формы регистрации:

<% if @user.new_record? %>
  <%= f.text_field :username %>
<% end %>

Наконец, в действии create вручную задайте поле имени пользователя, поскольку теперь оно находится в списке attr_accessible, и вы не можете массово назначить его:

@user = User.new(params[:user])
@user.username = params[:user][:username]

Пожалуйста, имейте в виду, если имя пользователя может быть установлено посредством массового назначения, даже если вы отключите поле имени пользователя в форме, оно все равно может быть изменено (его легко изменить в форме на стороне клиента) , Вот почему мы должны использовать attr_accessible для предзаказа.

Редактировать: заметил ваш частичный, лучше защитить поле администратора как имя пользователя, в противном случае пользователи могут установить себя как администратора, изменив значение поля на стороне клиента.

0 голосов
/ 20 апреля 2019

Вот мое решение аналогичной проблемы: у нас есть поля, которые мы хотим, чтобы пользователь мог устанавливать самостоятельно, мы не требуем их при создании записи, но мы НЕ хотим, чтобы они были изменены после установлены.

  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
0 голосов
/ 08 марта 2017

Хитрость заключается в том, чтобы использовать «объект» вместе с меткой для всего, что вы не хотите менять. Вот как вы должны кодировать его для имени пользователя:

<%= f.label(:username, f.object.username) %>
0 голосов
/ 17 февраля 2011

Как я вижу, у вас есть два способа сделать это.

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

надеюсь, что это поможет

ура

Самера

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...