0

在 Rails 4 上,我使用的是 Devise 登录。在第一次登录时,用户被定向到 new_profile_path(@user) 或 profile_path(@profile = @user.profile_id)。我在用户注册期间构建配置文件 ActiveRecord。我想将注册期间创建的 profile.id 传递回用户 ActiveRecord before_save。

我能够成功测试“after_create”,构建工作正常。然后“before_save”我可以通过硬编码 profile_id 来让它工作(见下面的工作代码)。但是,一整天后,我无法弄清楚传递 profile_id 的正确方法。我显然不想要一个硬编码的值。这是我的模型代码。

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

 has_one :profile, :dependent => :destroy, autosave: true
 accepts_nested_attributes_for :profile

 after_create :build_profile

 before_save :set_profile_id




 def build_profile
    Profile.create(user: self) # Associations must be defined correctly for this syntax, avoids using ID's directly.

  end

 def set_profile_id
    self.profile_id = 30 # Hard-coding tested and works. Profile built with user_id = user.id and user.profile_id = 30
 end

end



class Profile < ActiveRecord::Base

  belongs_to :user

  #validates :username, presence: true, length: {maximum: 255}, uniqueness: { case_sensitive: false }, format: { with: /\A[a-zA-Z0-9]*\z/, message: "deve contar apenas letras e números" }
  #validates :firstname, presence: true, length: {maximum: 255}
  #validates :lastname, presence: true, length: {maximum: 255}
  #validates :gender, presence: true, inclusion: %w(m f)
  #validates :birthday, presence: true

  has_many :offers, dependent: :delete_all

  before_save :set_address


  geocoded_by :address               # can also be an IP address

  def address
    address = "#{street_address}, #{city}, #{state}, #{zipcode}"
  end
  after_validation :geocode          # auto-fetch coordinates

  reverse_geocoded_by :latitude, :longitude
  after_validation :reverse_geocode  # auto-fetch address


  has_attached_file :logo_image, :styles => { :medium => "250x250>", :small => "175x175>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"

  # Validate content type
  validates_attachment_content_type :logo_image, :content_type => /\Aimage/
  # Validate filename
  validates_attachment_file_name :logo_image, :matches => [/png\Z/, /jpe?g\Z/, /JPG?\Z/]

  validates_attachment_size :logo_image, :less_than => 2.megabytes
  #validates_attachment_presence :avatar
  # Explicitly do not validate
  #do_not_validate_attachment_file_type :avatar


  # This may not be necessary anymore. With 'def address' above. Keeping for now as reference
  def set_address
    self.address = "#{street_address}, #{city}, #{state}, #{zipcode}"
  end



end



class RegistrationsController < Devise::RegistrationsController



  # GET /resource/sign_up
  def new
    build_resource({})
    @validatable = devise_mapping.validatable?
    if @validatable
      @minimum_password_length = resource_class.password_length.min
    end
    respond_with self.resource
  end

  # POST /resource
  def create
    build_resource(sign_up_params)

   resource_saved = resource.save
    yield resource if block_given?
    if resource_saved
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_flashing_format?
        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}" if is_flashing_format?
       expire_data_after_sign_in!
       respond_with resource, location: after_inactive_sign_up_path_for(resource)
     end
   else
     clean_up_passwords resource
     @validatable = devise_mapping.validatable?
     if @validatable
       @minimum_password_length = resource_class.password_length.min
     end
     respond_with resource
   end
 end


  private

  def sign_up_params
    params.require(:user).permit(:email, :password, :password_confirmation, :user_id, :profile_id)
  end

  def account_update_params
    params.require(:user).permit(:email, :password, :password_confirmation, :current_password, :user_id, :profile_id)
  end


end





class ProfilesController < ApplicationController

  before_action :set_profile, only: [:show, :edit, :update, :destroy]

  def index
    @profiles = Profile.all
    @hash = Gmaps4rails.build_markers(@profiles) do |profile, marker|
        marker.lat profile.latitude
        marker.lng profile.longitude
        marker.infowindow profile.address
    end
  end

  def address 
    @profile = Profile.find(params[:address])
    Geocode.search("@profile")
  end 

  def show
    @profiles = Profile.all
    @offers = Offer.where(user_id: current_user.id) 
    @hash = Gmaps4rails.build_markers(@profiles) do |profile, marker|
        marker.lat profile.latitude
        marker.lng profile.longitude
        marker.infowindow profile.address
    end

  end

  def new
    @user = current_user   # added to solve for session re-direct on sign-in
    @profile = Profile.new
  end

  def create
    @profile = Profile.new(profile_params)
    #@user.profile_id = @profile.id  # added to solve for session re-direct on sign-in
    if @profile.save

      flash[:notice] = "Profile has been created."

      redirect_to @profile
    else
      flash[:alert] = "Profile has not been created."

      render "new"
    end
  end

  def edit
    @hash = Gmaps4rails.build_markers(@profiles) do |profile, marker|
        marker.lat profile.latitude
        marker.lng profile.longitude
        marker.infowindow profile.address
      end  

  end

  def update
    if @profile.update(profile_params)
      flash[:notice] = "Profile has been updated."
      redirect_to @profile
    else
      flash[:alert] = "Profile has not been updated."
      render "edit"
    end
  end


  def destroy
    @profile.destroy

    flash[:notice] = "Profile has been destroyed."

    redirect_to profiles_path
  end




  private

    def profile_params
      params.require(:profile).permit(:id, :firstname, :lastname, :company, :website, :street_address, :city, :state, :zipcode, :phone, :logo_image, :address, :latitude, :longitude, :user_id, :user_email_id)
    end

    def set_profile
      @profile = Profile.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      flash[:alert] = "The profile you were looking for could not be found."
      redirect_to profiles_path
    end

end
4

0 回答 0