【问题标题】:Rails associations – How would you apply this user associationRails 关联——您将如何应用此用户关联
【发布时间】:2015-01-28 07:59:10
【问题描述】:

我一直在努力实现以下目标......

  1. 用户有很多联系人
  2. 联系人属于所有者,即用户
  3. 创建联系人不仅限于用户(例如,提交表单的非用户以及登录时添加新联系人的用户都可以创建联系人)。

目前,当我以用户身份创建联系人时,联系人的 owner_id 和 user_id 一直为零。

以下是我目前的情况...我犯了什么明显的错误可以快速解决它们吗?

模型

联系模特:

class Contact < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User'
  belongs_to :user
  validates :email, :presence => {:message => 'Email cannot be blank'}
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 :leadhooks
   has_many :contacts, :foreign_key => 'owner_id'
 # validates_formatting_of :website, using: :url
 # validates_formatting_of :phone, using: :us_phone
end

控制器

contacts_controller.rb

class ContactsController < InheritedResources::Base
before_action :set_contact, only: [:show, :edit, :update, :destroy]

  def index
    @user = current_user
    @contacts = @user.contacts.order("created_at DESC")
  end

  def show
  end

  def new
    @contact = Contact.new
  end

  def edit
  end

  def create
    @contact = Contact.new(contact_params)

  respond_to do |format|
    if @contact.save
        format.html { redirect_to @contact, notice: 'Contact was successfully created.' }
        format.json { render :show, status: :created, location: @contact }
    else
        format.html { render :new }
        format.json { render json: @contact.errors, status: :unprocessable_entity }
    end
   end
  end

 def update
   respond_to do |format|
     if @contact.update(contact_params)
       format.html { redirect_to @contact, notice: 'Contact was successfully updated.' }
       format.json { render :show, status: :ok, location: @contact }
     else
       format.html { render :edit }
       format.json { render json: @contact.errors, status: :unprocessable_entity }
     end
   end
 end

 def destroy
   @contact.destroy
     respond_to do |format|
      format.html { redirect_to contacts_url, notice: 'Contact was successfully destroyed.' }
      format.json { head :no_content }
   end
 end

 private

   # Use callbacks to share common setup or constraints between actions.
  def set_contact
    @contact = Contact.find(params[:id])
  end

  def contact_params
    params.require(:contact).permit(:name, :user_id, :email, :owner_id)
  end
 end

架构

create_table "contacts", force: true do |t|
t.string   "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string   "email"
t.integer  "user_id"
t.integer  "owner_id"
end

add_index "contacts", ["owner_id"], name: "index_contacts_on_owner_id", using: :btree
add_index "contacts", ["user_id"], name: "index_contacts_on_user_id", using: :btree

我一直在关注这里给出的答案...

How would you model contact list with self-reference and category?

但是,不知道为什么 user_id 和 owner_id 没有应用于联系人以及如何不将联系人的创建限制为仅用户(例如,允许通过非用户提交的表单创建联系人网页上的用户)

非常感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller associations


    【解决方案1】:

    您有几个不同的顾虑。解决第一个问题:

    1. "但是,不知道为什么 user_id 和 owner_id 没有应用于联系人"

    您似乎没有在控制器中建立关联。试试这样的:

    # controller
    def new
      @user = params[:user_id] # or @user = current_user, but you need to get a user
      @contact = @user.contacts.build
    end
    
    def create
      @user = params[:user_id] # or @user = current_user, but you need to get a user
      @contact = @user.contacts.build(contact_params)
      ...
    end
    

    2. “如何不将联系人的创建限制为仅用户(例如,允许通过非用户在网页上提交的表单创建联系人)”

    如果我理解正确,联系人就是人,就像学生在学校的档案中存储了多个紧急联系人一样。如果这是真的,那么您在这里要求的内容没有意义。您将始终希望将联系人的创建限制为用户。可以这样想:您只会在联系人的上下文中关心联系人,所以它需要一个所有者。想象一下学校里装满紧急联系人的盒子,卡片上没有学生姓名(我可能在这里约会自己......)这些卡片有什么用?

    如果您真的希望它为 nil,则在创建 Contact 的新实例时,您必须在控制器中允许 nil。比如:

    @contact = Contact.new(user: current_user) # will return nil if empty
    

    【讨论】:

    • 非常感谢@steel 的回复。通过编辑控制器中的“def create”,我能够将 user_id 应用于新联系人。关于第二个挑战,我没有说清楚是我的错误。我确实希望每个联系人都属于一个用户。但是,我希望网站访问者能够将自己添加为用户的新联系人(即电子邮件订阅者通过网络表单注册用户的时事通讯)。在控制器中,我们如何不阻止网站访问者成为用户的联系人?截至目前,只有登录用户才能填写表格并创建新联系人。
    • 啊,那不一样。 Rails 从不为您设置权限,因此阻止访问者创建联系人记录的任何内容都是您添加的内容,例如 Devise 回调。因此,为了不阻止访问者,您只需撤消您添加的任何内容(例如,可能跳过该方法的设计回调)。如果访问者提交表单,您会收到什么错误消息?如果可以,请发布该错误的堆栈跟踪的前五行左右。
    猜你喜欢
    • 1970-01-01
    • 2013-11-06
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2012-03-18
    相关资源
    最近更新 更多