2016-08-09 6 views
1

가입 할 때 사용자가 적어도 하나의 주소를 추가해야하는 유효성 검사를 추가하려고합니다. 사용자가 추가 한 각 주소는 새 주소 개체를 만듭니다. 현재, 내 사용자 모델은 다음과 같습니다.레일 4, 가입시 중첩 된 오브젝트의 존재 여부를 확인 하시겠습니까?

all_blank은 양식을 제출할 때 호출되지 않으며, check_addresses_number을 호출하는 유효성 검사 do 블록은 주소 개체처럼 보이기 때문에 항상 false를 반환합니다. 아직 만들어지지 않았다.

class User < ActiveRecord::Base 
    ADDRESSES_COUNT_MIN = 1 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    attr_reader :client 
    attr_accessor :addresses_attributes 

    has_many :carpools, foreign_key: "manager_id" 
    has_many :events, foreign_key: "driver_id" 
    has_many :events, foreign_key: "swap_requester_id" 

    # TODO Differentiate between 'sent invites' and 'invitations'? 
    has_many :invites, foreign_key: "sender_id" 

    has_many :carpool_memberships, foreign_key: "member_id", dependent: :destroy 
    has_many :carpools, through: :carpool_memberships 

    has_many :team_memberships, foreign_key: "member_id" 
    has_many :teams, through: :team_memberships 

    has_many :addresses, dependent: :destroy 
    accepts_nested_attributes_for :addresses, reject_if: :all_blank, allow_destroy: true 

    validate do 
     check_addresses_number 
    end 


    private 

     def all_blank(attributes) 
      byebug 
     end 


     def addresses_count_valid? 
      addresses.count >= ADDRESSES_COUNT_MIN 
     end 

     def check_addresses_number 
      unless addresses_count_valid? 
       errors.add(:base, :addresses_to_short, :count => ADDRESSES_COUNT_MIN) 
      end 
     end 

end 

내가 잘못 여기에 있는지 확인을하고 있어요 아니 무슨 teamsnap '을 ... 필요

UPDATE : 여기

내 사용자입니다 : 내가 주소를 건물입니다 RegistrationsController, 협회. 어쩌면 나는 그 장소에 협회를 짓고 있는가? #new 및 # 만들기 작업이 코드에서 특히 관심입니다

class Users::RegistrationsController < Devise::RegistrationsController 
prepend_before_action :require_no_authentication, only: [:new, :create, :cancel] 
before_action :configure_sign_up_params, only: [:create] 
# before_action :configure_account_update_params, only: [:update] 

include Users::InvitationsHelper 
include DeviseHelper 
    # GET /resource/sign_up 
    def new 
     @token = params[:invite_token] 
     build_resource({}) 
     set_minimum_password_length 
     yield resource if block_given? 
     self.resource.addresses.build 
     respond_with self.resource 

    end 

    # POST /resource 
    def create 
     build_resource(sign_up_params) 
     self.resource.addresses.build 
     resource.save 
     @token = params[:invite_token] 

    yield resource if block_given? 
    if resource.persisted? 
      if @token != nil 
       sign_up(resource_name, resource) 
       handle_invite_accept(@token) 
      else 
       if resource.active_for_authentication? 
        set_flash_message! :notice, :signed_up 
        sign_up(resource_name, resource) 
        respond_with resource, location: after_sign_up_path_for(resource) 
       else 
        set_flash_message! :notice, :"signed_up_but_#{resource.inactive_message}" 
        expire_data_after_sign_in! 
        respond_with resource, location: after_inactive_sign_up_path_for(resource) 
       end 
      end 
    else 
     clean_up_passwords resource 
     set_minimum_password_length 
     respond_with resource 
    end 
    end 

이 같은 #configure_sign_up_params는 모습입니다 :

def configure_sign_up_params 
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :email, :password, :password_confirmation, 
      :addresses_attributes => [:name, :country, :city, :address, :postal_code, :_destroy]]) 
    end 

는 또한, 난 그냥 눈치가 나는 주소 중 하나를 입력 할 때 필드를 작성하고 양식을 제출하면 user_id, created_at 및 updated_at 필드가 주소 레코드에 채워집니다. 그러나 폼이 제출 될 때 속성은 params 해시로 전달됩니다. 나는 레일 콘솔에서 마지막으로 생성 된 사용자를 찾을 때

Started POST "/users" for ::1 at 2016-08-09 20:37:48 -0400 
Processing by Users::RegistrationsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"4LSGSYdk/BwPDBC+li1btDR3KG3q8u9UrIkiyx9bZt+G+pV1o4uJhUZpa8UaqXnqSBva+aayrZ+sOk0vD+LO4g==", "user"=>{"name"=>"Matthew", "email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "addresses_attributes"=>{"1470789454196"=>{"name"=>"lkjhslkjdhf", "city"=>"lkjhslkdjfh", "address"=>"lkhsldkjhf", "postal_code"=>"lkjhslkdjhf", "_destroy"=>"false"}}}, "commit"=>"Sign up"} 
    (0.3ms) BEGIN 
    User Exists (0.9ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1 
    SQL (0.5ms) INSERT INTO "users" ("email", "encrypted_password", "name", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["email", "[email protected]"], ["encrypted_password", "$2a$11$v5n9eoBvN1Z./tYeujdyJOcNbC3x67G5JnGeqXPxkTnHQLff2gqR."], ["name", "Matthew"], ["created_at", "2016-08-10 00:37:48.679617"], ["updated_at", "2016-08-10 00:37:48.679617"]] 
    SQL (1.1ms) INSERT INTO "addresses" ("user_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["user_id", 6], ["created_at", "2016-08-10 00:37:48.681451"], ["updated_at", "2016-08-10 00:37:48.681451"]] 
    (0.6ms) COMMIT 
    (0.2ms) BEGIN 
    SQL (0.5ms) UPDATE "users" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "last_sign_in_ip" = $3, "current_sign_in_ip" = $4, "sign_in_count" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["last_sign_in_at", "2016-08-10 00:37:48.684863"], ["current_sign_in_at", "2016-08-10 00:37:48.684863"], ["last_sign_in_ip", "::1/128"], ["current_sign_in_ip", "::1/128"], ["sign_in_count", 1], ["updated_at", "2016-08-10 00:37:48.685680"], ["id", 6]] 
    (0.4ms) COMMIT 
Redirected to http://localhost:3000/ 
Completed 302 Found in 199ms (ActiveRecord: 4.5ms) 


Started GET "/" for ::1 at 2016-08-09 20:37:48 -0400 
Processing by VisitorsController#index as HTML 
    Rendered layouts/_navigation_links.html.erb (0.1ms) 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 6]] 
    Rendered layouts/_nav_links_for_auth.html.erb (2.2ms) 
    Rendered layouts/_navigation.html.erb (3.8ms) 
    Rendered visitors/_teamsnap_member_modal.html.erb (0.1ms) 
    Rendered visitors/index.html.erb within layouts/application (5.5ms) 
    Rendered layouts/_messages.html.erb (0.1ms) 
Completed 200 OK in 53ms (Views: 52.6ms | ActiveRecord: 0.5ms) 

는 내가 얻을이 :

irb(main):001:0> User.last.addresses 
    User Load (2.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1 
    Address Load (1.4ms) SELECT "addresses".* FROM "addresses" WHERE "addresses"."user_id" = $1 [["user_id", 6]] 
=> #<ActiveRecord::Associations::CollectionProxy [#<Address id: 7, name: nil, country: nil, city: nil, address: nil, postal_code: nil, user_id: 6, created_at: "2016-08-10 00:37:48", updated_at: "2016-08-10 00:37:48">]> 

업데이트 2 :

이 어둠 속에서 촬영, 그리고 난 왜 이것이 문제를 해결할 지 확신하지 못합니다. 어쨌든 attr_accessor :addresses_attributes 을 사용자 모델에서 제거했습니다. 그리고 그것은 내 문제를 해결했습니다. 그 코드 라인은 의미가 없기 때문에 필요하지 않습니다. 제거한 후 주소 개체 생성이 예상대로 작동하기 시작했습니다. 중첩 된 속성의

+1

당신의'validate ... do'은 이상한 구조입니다. 대신'validate : check_addresses_number'를 시도하십시오. 또한 :'all_blank'는 확인할 주소가있는 경우에만 호출됩니다. 주소를 추가하는 데 사용하는 양식을 표시 할 수 있습니까? 서버 로그를 살펴보고 주소가 포함 된'params' 해시의 예를 들어 보겠습니다. 또한 : 주소가 당신의 컨트롤러의'permit/require' 섹션에 있는지 확인 했습니까? –

+0

개체가 잘 생성되고 있습니다. 제출시에 적어도 하나의 중첩 된 생성에 대한 유효성 검사를 추가하기 위해 고심하고 있습니다. 나는 더 많은 정보를 게시 할 것이다 – matthewalexander

+0

ACtually, 나는 단지 주소 객체가 제대로 만들어지지 않고 있다는 것을 알아 차렸다. ... 그들은 일주일 전이었다. 그리고 지금 그들은 그렇지 않습니다! – matthewalexander

답변

0

확인 :

은 중첩 된 속성이 속한있는 모델의 유효성 검사 규칙을 사용하여 유효성을 검사합니다. 특성을 허용하는 모델에서 정의 할 필요는 없습니다. 중첩 된 특성을 사용하는 모델에서는 accept_nested_attributes_for :modelname을 사용하고 기본 모델에서는 특성이 속한 모델에 validates_presence_of :attribute을 사용하십시오.

+2

이것은 도움이되지 않습니다. 저자는 주소가 * 주소인지 아닌지 확인하려고하는데 주소에 대한 속성이 유효하지는 않습니다 ... 이것은 부모 개체에서해야 할 일입니다 –

관련 문제