如何将模型与多个模型正确关联?

时间:2014-12-17 17:32:19

标签: ruby-on-rails ruby ruby-on-rails-4

我已尝试在相关问题中实施许多建议的解决方案,但尚未找到适合我在Rails 4应用程序中尝试实现的解决方案。

基本上我的应用程序有三种型号。用户,挂钩(可嵌入的弹出窗口小部件)和联系人。用户可以在其界面中创建挂钩和联系人。任何访问者都可以通过填写Hook视图中的联系人创建表单来创建新联系人,并且该联系人与创建该联系人的用户相关联。

工作正常,但是当通过填写Hook的表单创建联系人时,他们没有连接到他们完成表单的特定Hook。

我想要添加到我的应用程序的下一组功能不仅需要将每个联系人与用户相关联,还需要将其与创建的特定Hook相关联。

我已经读过多态关联(模型属于多个模型),我理解这可能是要走的路。经过几次尝试失败后,我不确定如何实现它。

如何将联系人与Hook关联,以便用户可以知道从哪个联系人创建联系人?

以下是我目前在Hooks控制器和模型中的内容......

def create
    @hook = hook.new(hook_params)
    @hook.user = current_user
    @contact = Contact.new(contact_params)

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

class Hook < ActiveRecord::Base

belongs_to :user
  has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "https://s3.amazonaws.com/app/assets/leadmagnet.png"
  validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end

这是联系人控制器和模型......

def create
    @contact = Contact.new(contact_params)
    @contact.user = current_user

    respond_to do |format|
    if @contact.save
          if user_signed_in?
            format.html { redirect_to @contact, notice: 'Contact was successfully created.' }
          else
            format.html { redirect_to @contact, notice: 'Contact was successfully created.' }
          end
          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

class Contact < ActiveRecord::Base

belongs_to :owner, :class_name => 'User'
  belongs_to :user
  validates :email, :presence => {:message => 'Email cannot be blank'}
end

2 个答案:

答案 0 :(得分:1)

首先,你永远不应该在同一个控制器动作上创建2个不相关的模型。它打破了惯例,只会导致问题。

您无需直接将联系人与用户关联。您应该将联系人关联到挂钩,然后通过挂钩关联联系人

class User < ActiveRecord::Base
    has_many :hooks
    has_many :contacts, through: :hooks
end

class Hook < ActiveRecord::Base
    belongs_to :user
    has_many :contacts

    accepts_nested_attributes_for :contacts
end

class Contact < ActiveRecord::Base
    belongs_to :hook
end

现在,在ContactsController的创建操作中,您可以先通过URL参数获取Hook,也可以通过post body传递。您可以先找到Hook并通过以下方式在其上创建联系人:

hook = Hook.find(hook_id)
@contact = hook.contacts.new(contacts_param)

如果要在创建新Hook时创建联系人,则需要在strong_params上添加:contacts_attributes,然后通过POST传递一组联系人属性。将accepts_nested_attributes_for添加到Hook模型中,您只需输入以下内容,即可在创建Hook时轻松创建联系人:

@hook = Hook.new(hook_params)

答案 1 :(得分:0)

如果我理解正确,您想同时创建HookContact,并将两者都关联到current_user。在您的代码中,您可以创建两者,但只将@hookcurrent_user相关联,并且只保存它,而忽略@contact。只需将其关联并保存即可:

def create
    @hook = hook.new(hook_params)
    @hook.user = current_user
    @contact = Contact.new(contact_params)
    @contact.user = current_user

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