Ruby on rails 如何使用另一个模型的属性填充多个表单字段?

Ruby on rails 如何使用另一个模型的属性填充多个表单字段?,ruby-on-rails,ajax,devise,associations,Ruby On Rails,Ajax,Devise,Associations,我有3个模型-用户,发货和友谊。用户可以通过友谊模型与其他用户成为朋友。用户还可以创建发货,并可以向其中添加朋友用户。在用户和发货模型中存在地址属性。我需要为用户提供一种可能性,以两种方式在同一表格中填写该地址字段: 通过手动填写地址字段 通过从“选择列表”中选择该用户的一个朋友,那么 地址属性传输并填充装运地址属性 (如ctrl-c/ctrl-v),用户可以提交表单 我可以猜测,需要AJAX来刷新内容而不刷新页面 装运模式: class Shipment < ActiveRecord::

我有3个模型-用户,发货和友谊。用户可以通过友谊模型与其他用户成为朋友。用户还可以创建发货,并可以向其中添加朋友用户。在用户和发货模型中存在地址属性。我需要为用户提供一种可能性,以两种方式在同一表格中填写该地址字段:

  • 通过手动填写地址字段
  • 通过从“选择列表”中选择该用户的一个朋友,那么 地址属性传输并填充装运地址属性 (如ctrl-c/ctrl-v),用户可以提交表单
  • 我可以猜测,需要AJAX来刷新内容而不刷新页面

    装运模式:

    class Shipment < ActiveRecord::Base
      belongs_to :user
      belongs_to :friendship
    
      validates :image, presence: true
      validates :user_id, presence: true
    end
    
    装运表单视图(新):

    
    从朋友列表中选择朋友或手动填写地址字段:


    使用ActiveRecord::Base,您可以使用即时加载和嵌套表单来解决问题


    加载与主对象相关的对象,并使用嵌套形式显示相关对象

    简言之,是的,它将使用ajax获取朋友的地址,但在这种情况下,您不需要在表单字段中执行任何操作——只需创建一个div,javascript可以绑定到该div以文本格式显示地址即可虽然我认为您可能缺少地址模型,因此您可以拥有地址的所有必要字段(街道名称/号码、额外信息/城市/地区/州/邮政编码)
    class ShipmentsController < ApplicationController
    
      helper_method :shipment, :user
      before_action :set_shipment, only: [:show]
      before_action :authenticate_user!
      before_action :require_same_user, only: [:show]
    
      def index
        @shipments = Shipment.all
      end
    
      def new
        @shipment = Shipment.new
      end
    
      def create
        @shipment = Shipment.new(shipment_params)
        @shipment.user = current_user
        if @shipment.save
          flash[:success] = "Shipment etc."
          redirect_to shipment_path(@shipment)
        else
          render 'new'
        end
      end
    
      def show
        @shipment = Shipment.find(params[:id])
      end
    
      private
    
        def user
          @user = current_user
        end
    
        def shipment
          @shipment = user.shipments.new
        end
    
        def shipment_params
          params.require(:shipment).permit(:name, :kg, :length, :width, :height,
                                           :adress, :image, :user_id, :friend_id)
        end
    
        def set_shipment
          @shipment = Shipment.find(params[:id])
        end
    
        def require_same_user
          if current_user != @shipment.user
            flash[:alert] = "Restricted/"
            redirect_to root_path
          end
        end
    
    end
    
    class User < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, :validatable
    
      has_many :shipments, dependent: :destroy
      has_many :friendships
      has_many :friends, through: :friendships
      has_many :inverse_friendships, :class_name => 'Friendship', 
                                     :foreign_key => 'friend_id'
      has_many :inverse_friends, :through => :inverse_friendships, :source => :user
    
    end
    
    class UsersController < ApplicationController
    
      before_action :authenticate_user!
    
      def show
        @user = User.find(params[:id])
      end
    
      def my_friends
        @friendships = current_user.friends
      end
    
      def search
        @users = User.search(params[:search_param])
        if @users
          @users = current_user.except_current_user(@users)
          render partial: 'friends/lookup'
        else
          render status: :not_found, nothing: true
        end
      end
    
      private
    
        def require_same_user
          if current_user != set_user
            flash[:alert] = "Restricted."
            redirect_to root_path
          end
        end
    
        def set_user
          @user = User.find(params[:id])
        end
    
    end
    
    class Friendship < ActiveRecord::Base
    
      belongs_to :user
      belongs_to :friend, class_name: 'User'
      has_many :shipments
    
    end
    
    class FriendshipsController < ApplicationController
    
      def index
        @friendships = Friendship.all
      end
    
      def create
        @friendship = current_user.friendships.build(:friend_id => params[:friend_id])
        if @friendship.save
          flash[:success] = "Added to friends."
          redirect_to my_friends_path
        else
          flash[:alert] = "Impossible to add as a friend."
          redirect_to my_friends_path
        end
      end
    
      def destroy
        @friendship = current_user.friendships.find_by(friend_id: params[:id])
        @friendship.destroy
        flash[:notice] = "Unfriended."
        redirect_to my_friends_path
      end
    
      private
    
        def name
          @name = friend_id.name
        end
    
    end
    
    create_table "friendships", force: :cascade do |t|
        t.integer  "user_id"
        t.integer  "friend_id"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
    
      create_table "shipments", force: :cascade do |t|
        t.string   "name"
        t.integer  "length"
        t.integer  "width"
        t.text     "adress"
        t.integer  "user_id"
        t.datetime "created_at",         null: false
        t.datetime "updated_at",         null: false
        t.string   "image_file_name"
        t.string   "image_content_type"
        t.integer  "image_file_size"
        t.datetime "image_updated_at"
        t.integer  "height"
        t.integer  "kg"
      end
    
      add_index "shipments", ["user_id"], name: "index_shipments_on_user_id"
    
      create_table "users", force: :cascade do |t|
        t.string   "email",                             default: "", null: false
        t.string   "encrypted_password",                default: "", null: false
        t.string   "reset_password_token"
        t.datetime "reset_password_sent_at"
        t.datetime "remember_created_at"
        t.integer  "sign_in_count",                     default: 0,  null: false
        t.datetime "current_sign_in_at"
        t.datetime "last_sign_in_at"
        t.string   "current_sign_in_ip"
        t.string   "last_sign_in_ip"
        t.datetime "created_at",                                     null: false
        t.datetime "updated_at",                                     null: false
        t.string   "name"
        t.integer  "phone",                  limit: 30
        t.string   "username"
      end
    
      add_index "users", ["email"], name: "index_users_on_email", unique: true
      add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    
    <%= form_for(shipment, html: { multipart: true }) do |f| %>
    <p>Choose a friend from your friendlist or fill the address field manually:</p>
    <%= f.select :friend_id, user.friendships.map{ |friendship| 
                                        [friendship.friend.name, friendship.id] } %>
      <%= f.text_field :adress, placeholder: "Address and index" %>
      <%= f.submit "Submit", class: "button" %>
    <% end %>