Ruby on Rails Association构建并分配2个相关的关联

时间:2016-05-10 21:59:10

标签: ruby-on-rails ruby syntax

所以我有WM_VSCROLL模型,User模型和Building模型。

用户MaintenanceRequest,但has_many :maintenance_requests

维护请求belongs_to :buildingbelongs_to :building

我试图找出如何发送新内容,然后创建维护请求。

我想做的是:

belongs_to: user

并向用户提出新的维护请求,并将其设置为其父级关联。

我必须做的事情:

@maintenance_request = current_user.building.maintenance_requests.build(permitted_mr_params)
=> #<MaintenanceRequest id: nil, user_id: 1, building_id: 1> 

如果我能够根据用户的建筑物获得维护请求,那就太好了。

显然,我可以解决这个问题,但我真的很感激语法糖。

3 个答案:

答案 0 :(得分:1)

在我看来,我认为你提出的方法很好。它是一个额外的代码行,但并没有真正增加控制器的复杂性。

另一种选择是在您的请求参数中合并user_idbuilding_id

permitted_mr_params.merge(user_id: current_user.id, building_id: current_user.building_id)
@maintenance_request = MaintenanceRequest.create(permitted_mr_params)

或者,如果您不关心批量分配,请将user_idbuilding_id设置为表单中的隐藏字段。但是,我不会看到巨大的好处,因为你必须将参数列入白名单。

答案 1 :(得分:1)

我的方法是跳过

maintenance_request belongs_to :building

因为它已经通过用户属于它。相反,您可以定义方法

class MaintenanceRequest
    belongs_to :user

    def building
        user.building
    end

    #more class stuff
end

另外,在建筑类

class Building
     has_many :users
     has_many :maintenance_requests,  through: :users

    #more stuff
end

因此,您可以完全省略与maintenance_request的显式构建关联

<强>更新 由于用户可以在建筑物之间移动,因此您可以使用回调设置自动行为。这项工作将像你一样完成,但采用更多的Railsey方式

class MaintenanceRequest
     #stuff
     before_create {
         building=user.building
     }
end

因此,当您为用户创建maintenance_request时,将相应地设置建筑物

答案 2 :(得分:1)

来自has_many doc

  

您可以将第二个参数范围作为可调用的(即proc或lambda)传递,以检索特定的记录集,或在访问关联的集合时自定义生成的查询。

class User < ActiveRecord::Base
  has_many :maintenance_requests, ->(user){building: user.building}, through: :users
end

然后你想要的一行应该“正常工作”current_user.building.maintenance_requests.build(permitted_mr_params)

或者,如果您使用cancancan,则可以在能力文件中添加哈希条件

can :create, MaintenanceRequest, user: @user.id, building: @user.building_id