【问题标题】:Multiple t.references get nil with nested models嵌套模型的多个 t.references 为零
【发布时间】:2016-04-08 21:31:29
【问题描述】:

我正在为用户使用设计。

用户.rb

belongs_to shop
has_many tasks

Show.rb

has_many users
has_many tasks

Task.rb

belongs_to user
belongs_to shop

当我创建一个新任务时:

current_user.tasks.create(...)

shop_id 的值为零,当我需要与用户相同的shop_id 时。

当我创建一个新任务时

  current_user.shop.tasks.create(...)

我将 user_id 设为 nil,但得到了 shop_id 的正确值。

我错过了什么?

提前致谢。

【问题讨论】:

  • 你有没有尝试在rails console运行?
  • 是的,结果相同。
  • 你可以试试这个User.first.tasks.create(...) 吗?
  • 现在以某种方式工作...... !!!!!将其发布为答案或其他内容,我会标记它。
  • 这现在只能在控制台中以某种方式工作,奇怪!

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


【解决方案1】:

current_user.tasks.create(...)

运行 rails 协会不会知道它必须填充 shop_id,除非您明确发送它

current_user.tasks.create(shop_id: current_user.shop.id)

反之亦然。对于这种情况,您可以使用用户、商店和任务之间的多态关联来使用更好的建模。更多细节和例子可以在这里找到。

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

不要认为这与设计有关。

【讨论】:

    【解决方案2】:

    current_user.shop.tasks.create(...) 中,您直接在tasks 集合上调用create 以获得单数shop。这实际上等同于:

    Shop.find_by(user_id: current_user.id).tasks.create(...)
    

    商店可能有多个用户,因此该声明中没有明确说明新创建的任务应属于current_user

    我认为最简单的解决方案是自己创建任务,显式设置两个外键:

    Task.create(shop_id: current_user.shop_id, user_id: current_user.id)
    

    尽管您必须重新加载您的 usershop 引用才能获取新关联的 task

    如果您想要更自动化的东西,请考虑在用户内对has_many :tasks 使用关联回调,其中shop_idTask 是从user 的shop_id 设置的:

    class user < ActiveRecord::Base
      belongs_to :shop
      has_many :tasks, before_add: :assign_to_shop
    
      def assign_to_shop(task)
        task.shop = self.shop
        ...
      end
    end
    

    【讨论】:

      【解决方案3】:

      设计current_user 方法返回用户的相同对象。

      # simple example
        def sign_in 
          session[:current_user] = User.find_by_email(params[:email])
        end
      
        def current_user
         session[:current_user]
        end
      

      如果用户登录,那么current_user 方法应该可以工作,如下所示。

      #1
      current_user.tasks.create(...)
      
      #2 you can also like this
      t = Task.new(...)
      t.user_id = current_user.id
      t.save
      

      你可以在rails console玩,简单易懂。

      current_user = User.first
      current_user.tasks.create(...)
      

      【讨论】:

      • 我什么也没做,这仅在控制台上有效,并且不知何故停止了。我知道这听起来很疯狂,但没错!
      • @KamalG'ool 你登录了吗?
      • 我做到了,我在控制器中修复了这个问题,每次根据current_user创建,分配商店和用户时,我都会稍后发布答案。
      猜你喜欢
      • 1970-01-01
      • 2014-06-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2016-06-29
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多