创建的数据:通过关系

创建的数据:通过关系

问题描述:

我会问我的问题第一:创建的数据:通过关系

将这段代码逻辑上工作,它是做(最佳实践角度)正确的事?首先,让用户被传递给静态订阅方法看起来很奇怪

用户和杂志通过订阅(定义见下文)有多对多的关系。你也可以看到,我通过连接来使用,而不是使用has而且属于很多,这样我们就可以定义一个订阅模型。

创建用户后,他们需要有默认订阅。遵循单一责任原则,我认为用户不应该知道要订阅哪些默认杂志。那么,在创建用户后,如何创建默认订阅。 user.likes_sports? user.likes_music?应该定义我们想要的订阅方法。

我在正确的轨道上吗?我没有任何人审查我的代码,任何代码建议高度赞赏。

class User < ActiveRecord::Base 
    after_create create_default_subscriptions 

    has_many :magazines, :through => :subscriptions 
    has_many :subscriptions 

    def create_default_subscriptions 
     if self.likes_sports? 
      Subscription.create_sports_subscription(self) 
     end 
    end 
end 

class Subscription < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :magazine 

    #status field defined in migration 

    def self.create_sports_subscription(user) 
    Magazine.where("category = 'sports'").find_each do |magazine| 
     user.subscriptions << Subscription.create(:user => user, :magazine => magazine, :status=>"not delivered") 
    end 
    end 
    . 
    . 
end 

class Magazine < ActiveRecord::Base  
    has_many :users, :through => :subscriptions 
    has_many :subscriptions 
end 
+0

你想添加方法给你的用户来检查用户“likes_sports?”或你想做什么?在创建用户后创建一些其他记录? – Hendrik

+0

做了一个编辑,问题是在帖子的顶部 – user1438150

在我看来,代码太耦合了。这可以非常容易地失控。

要做到这一点,我认为是创建一个新的服务/表单需要创建用户的照顾你

class UserCreationService 

    def perform 
    begin 
     create_user 
    # we should change this to only rescue exceptions like: ActiveRecord::RecordInvalid or so. 
    rescue => e 
     false 
    end 
    end 

    private 

    def create_user 
    user = nil 
    # wrapping all in a transaction makes the code faster 
    # if any of the steps fail, the whole user creation will fail 
    User.transaction do 
     user = User.create 
     create_subscriptions!(user) 
    end 
    user 
    end 

    def create_subscriptions!(user) 
    # your logic here 
    end 
end 

然后调用代码在您的控制器像这样正确的做法:

def create 
    @user = UserCreationService.new.perform 
    if @user 
    redirect_to root_path, notice: "success" 
    else 
    redirect_to root_path, notice: "erererererooooor" 
    end 
end 
+0

很高兴听到另一个角度,非常感谢你 – user1438150

+0

不客气:)。几乎所有的东西都使用表单对象。 – Hendrik