2015-10-03 47 views
2

昨天我問了這樣一個問題,但在我花了幾個小時處理了這個問題之後,我瞭解到,我昨天問的問題不是我遇到的問題。所以,我決定再問一次。驗證僅限於表單中的值

用戶模型:

EMAIL_REGEX = /\A^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$\z/ 
    # Matches -> [email protected] [email protected] [email protected] 
    # Non-Matches -> [email protected]_d.com he&[email protected] [email protected]#.co.uk 
    # http://regexlib.com/REDetails.aspx?regexp_id=333 

    ALL_LETTERS_AND_SINGLE_SPACES = /\A^([a-zA-Z]+\s?)*$\z/ 
    ALL_LETTERS_AND_NUMBERS = /\A^[a-zA-Z0-9]+$\z/ 
    WEBSITE = /\A(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?\z/ 

    # First Name 
    validates :first_name, 
      presence: {message: 'First name cannot be blank'}, 
      length: {maximum: 50, message: 'First name cannot be longer than 50 characters'}, 
      format: {with: ALL_LETTERS_AND_SINGLE_SPACES, message: 'First name should contain only letters and single space'} 

    # Last Name 
    validates :last_name, 
      presence: {message: 'Last name cannot be blank'}, 
      length: {maximum: 50, message: 'Last name cannot be longer than 50 characters'}, 
      format: {with: ALL_LETTERS_AND_SINGLE_SPACES, message: 'Last name should contain only letters and single space'} 

    # Email 
    validates :email, 
      presence: {message: 'Email cannot be blank'}, 
      length: {maximum: 100, message: 'Email cannot be longer than 100 characters'}, 
      format: {with: EMAIL_REGEX, message: 'Email is not valid'}, 
      uniqueness: {case_sensitive: false, message: 'This email is already registered'}, 
      confirmation: {message: 'Email address does not match'} 

    # Password 
    validates :password_digest, 
      presence: {message: 'Password cannot be blank'}, 
      length: {minimum: 8, message: 'Password length should be minimum 8 characters'} 

    # Username 
    validates :username, 
      presence: {message: 'Username cannot be blank'}, 
      length: {minimum: 3, message: 'Email cannot be shorter than 3 characters'}, 
      format: {with: ALL_LETTERS_AND_NUMBERS, message: 'Username should contain only letters and numbers'}, 
      uniqueness: {case_sensitive: false, message: 'This username is already in use'} 

    # Website 
    validates :website, 
      format: {with: WEBSITE, message: 'Invalid email format. Make sure you don\'t have http:// in your link'} 

    # Information 
    validates :information, 
      length: {maximum: 100, message: 'Information cannot be longer than 99 characters'} 

正如你所看到的,我有我的數據庫中的一些列的驗證。我需要的是在用戶註冊時驗證first_name,last_name,email和password,並在用戶編輯他/她的個人資料設置時驗證first_name,last_name以及網站,信息和用戶名。

但是,rails會自動驗證您的註冊頁面中是否有用戶名字段的所有列。它只是驗證一切。但我不希望Rails在註冊時驗證用戶名或網站。

檔案控制器:

def update 
    # Find an existing object using form parameters 
    @profile = User.find_by_id(current_user.id) 
    # Update the object 
    if @profile.update_attributes!(settings_profile_params) 
     # If save succeeds, redirect to itself 
     redirect_to request.referrer 
    else 
     # If save fails, redisplay the form so user can fix the problems 
     render('edit') 
    end 
    end 

    private # user_params is not an action, that is why it is private. 
    def settings_profile_params 
    params.require(:user).permit(:first_name, :last_name, :username, :school, :program, :website, :information) 
    end 

用戶控制器:

def create 
    # Instantiate a new object using form parameters 
    @user = User.new(user_params) 
    # Save the object 
    if @user.save 
     # If save succeeds, redirect to the dashboard action 
     cookies[:authorization_token] = @user.authorization_token 
     redirect_to dashboard_path 
    else 
     # If save fails, redisplay the form so user can fix the problems 
     render('new') 
    end 
    end 

    private # user_params is not an action, that is why it is private. 
    def user_params 
    params.require(:user).permit(:first_name, :last_name, :email, :email_confirmation, :password) 
    end 

我想軌將驗證在強大的參數只有通過者,但事實並非如此。我相信它應該很容易解決,但我不能。

謝謝。

回答

-1

您可以使用:如果選項:

class Order < ActiveRecord::Base 
    validates :card_number, presence: true, if: :paid_with_card? 

    def paid_with_card? 
    payment_type == "card" 
    end 
end 

但我認爲你正在尋找allow_nil或allow_blank選項:

3.1:allow_nil

的:allow_nil選項當驗證值 爲零時跳過驗證。

class Coffee < ActiveRecord::Base 
    validates :size, inclusion: { in: %w(small medium large), 
    message: "%{value} is not a valid size" }, allow_nil: true 
end 

3.2:allow_blank

的:allow_blank選項類似於:allow_nil選項。如果屬性的值爲空,這個 選項會讓驗證通過嗎?, 比如nil或空字符串。

class Topic < ActiveRecord::Base 
    validates :title, length: { is: 5 }, allow_blank: true 
end 

Topic.create(title: "").valid? # => true 
Topic.create(title: nil).valid? # => true 
1

我不知道要做到這一點的慣用方式。對於要只更新運行單個驗證,你可以做

validates :username, 
... 
on: :update # or on: :create 

或者,如果你希望他們只當屬性已在形式被提供運行,

validates :username, 
... 
if: :username_changed? 

對於更激進解決方案時,您可能需要考慮將您的模型分成兩部分 - 一部分包含註冊時創建的屬性(User),另一部分包含其他屬性(UserDetailsUserProfilebelongs_to :user。此時,在工作流程的不同階段擁有不同的驗證邏輯變得非常簡單。

+0

這些都是很好的建議。讓我在他們身上工作一段時間。我希望他們會工作。 – cyonder

+0

事情是我有不同的更新形式。如果您有GitHub帳戶,請檢查設置。我正在嘗試這樣做。要改變密碼,我使用不同的形式,並改變first_name我使用不同的形式。所以,最後我需要以不同的形式驗證它們。所以我不能使用on:create或on:update屬性。這真的很奇怪。爲什麼,軌道沒有驗證我正在嘗試羣發的那些。 – cyonder

0

模型驗證大部分時間都是關於表單的。

Ryan Bates已經發布了an excellent RailsCast關於如何重構你的模型,方式是你爲每個表單使用不同的對象。

這樣,您可以組合模型和/或定義不同的行爲和/或驗證,具體取決於提交數據的表單。

要做到這一點的方式很長,所以在這裏發佈代碼會很麻煩。

我強烈建議訪問上面的鏈接,你會在那裏得到你的答案。