2016-04-10 4 views
0

Ich habe 3 Modelle - Benutzer, Versand und Freundschaft. Benutzer kann mit einem anderen Benutzer über Friendship-Modell befreundet sein. Der Benutzer kann auch Sendungen erstellen und ihm einen Freund-Benutzer hinzufügen. Es gibt ein Adressattribut in den Benutzer- und Versandmodellen. Ich muss dem Benutzer eine Möglichkeit geben, dieses Adressfeld auf zwei Arten auf dem gleichen Formular zu füllen:Wie füllt man mehrere Formularfelder mit einem Attribut aus einem anderen Modell?

  • Indem Sie das Adressfeld manuell ausfüllen.
  • Durch die Auswahl aus der Liste ein Freund dieses Benutzers - so die Freunde Adresse-Attribut überträgt und füllt die Sendungen Adresse-Attribut (wie ctrl-c/ctrl-v) und Benutzer kann das Formular einreichen.
  • Ich kann schätzen, dass AJAX benötigt wird, um den Inhalt zu aktualisieren, ohne die Seite zu aktualisieren.

    Versand Modell:

    class Shipment < ActiveRecord::Base 
        belongs_to :user 
        belongs_to :friendship 
    
        validates :image, presence: true 
        validates :user_id, presence: true 
    end 
    

    Sendungen Controller:

    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 
    

    User-Modell:

    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 
    

    Benutzer-Controller (der Benutzer selbst durch Devise erstellt wird)

    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 
    

    Friendship Modell:

    class Friendship < ActiveRecord::Base 
    
        belongs_to :user 
        belongs_to :friend, class_name: 'User' 
        has_many :shipments 
    
    end 
    

    Friendships Controller:

    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 
    

    Schema:

    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 
    

    Sendungsformularansicht (neu):

    <%= 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 %> 
    
    +0

    Kurz gesagt, ja, es würde Ajax verwenden, um die Adresse des Freundes zu packen, aber Sie müssten in den Formularfeldern in diesem Fall nichts tun - erstellen Sie einfach ein div, an das JavaScript binden könnte, um die Adresse im Text anzuzeigen Format. - Obwohl ich denke, dass Sie ein Adressmodell vermissen, können Sie alle notwendigen Felder einer Adresse (Straßenname/Nummer, zusätzliche Informationen/Stadt/Region/Bundesland/Postleitzahl) haben – trh

    Antwort

    0

    Mit ActiveRecord :: Base können Sie das Problem durch Laden und verschachtelte Formulare lösen.

    Eager laden das Objekt in Bezug auf das Hauptobjekt und verschachtelte Formular verwenden, um das zugehörige Objekt anzuzeigen.

    Verwandte Themen