【问题标题】:Rails 4, How do I create a new model instance from a string field in a form?Rails 4,如何从表单中的字符串字段创建新模型实例?
【发布时间】:2013-10-28 21:57:23
【问题描述】:

在 Rails 4 中执行以下操作的正确方法是什么?我有一个表格,它接受一个字符串和一个特定模型的其他一些参数,比如说 Foo。该模型与另一个模型有关联,

class Foo < ActiveRecord::Base
  belongs_to :bar
end

我想从给定的字符串创建一个新的 Bar,假设数据库中不存在同名的 Bar。

我最初的方法是在控制器级别执行此操作,基本上从参数中获取名称,然后尝试从中创建一个对象并改变原始参数以包含新对象而不是原始字符串。但我意识到这不是非常惯用的 Rails,我应该完全在模型级别这样做。

那么我将如何在模型级别完成我想做的事情?我想我需要一个瞬态属性和某种before_validation 过滤器,但我对Rails 不是很熟悉。有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    不确定是否正确理解您要做什么,但您可能想看看rails nested attributes

    你会有一个像下面这样的 Foo 类:

    class Foo < ActiveRecord::Base
      has_one :bar
    
      accepts_nested_attributes_for :bar
    end
    
    class Bar < ActiveRecord::Base
      belongs_to :foo
    end
    

    您可以像这样创建一个直接关联到 Foo 的新 Bar 实例:

    foo = Foo.new(bar_attributes: { name: "Bar's name" })
    foo.bar.name
    #=> "Bar's name"
    

    【讨论】:

    • 谢谢,这很有意义
    • 欢迎您,您可能想看看 rails 4 如何将嵌套参数处理为强参数here
    【解决方案2】:

    为什么需要改变参数? IMO 这应该在控制器级别完成,但根本不更改任何参数。

    class FoosController
    
      before_filter :set_foo
      before_filter :set bar
    
      def update
        @foo.bar = @bar
        @foo.update(foo_params)
        respond_with @foo
      end
    
      private 
    
        def set_foo
          @foo = Foo.find(params[:id])
        end
    
        def set_bar
          @bar = # create/find your Bar from the params here
        end
    
        def foo_params
          params.require(:foo).permit(...)
        end
    
    end
    

    【讨论】:

    • 对不起,我没有完全解释清楚,我需要改变参数的原因是因为我正在扩展一个现有的控制器(设计注册控制器)并调用 super。
    猜你喜欢
    • 2011-04-19
    • 2010-10-13
    • 2012-06-10
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多