我有三个模型-用户、发货和友谊。用户可以通过友谊模型与其他用户成为朋友。用户还可以创建发货,并可以向其中添加好友用户。用户和发货模型中有地址属性。我需要给用户一种在同一表格中用两种方式填写地址字段的可能性:
- 通过手动填写地址字段
- 通过从选择列表中选择该用户的好友,则好友address属性传输并填充Shipments地址属性(如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
发货控制器:
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
用户控制器(用户本身由Devise创建)
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 %>
使用ActiveRecord::Base,您可以使用热切加载和嵌套表单来解决问题。
Eager加载与主对象相关的对象,并使用嵌套形式显示相关对象。