使用Cocoon gem时,将嵌套属性记录分配给当前用户

时间:2017-04-27 13:23:46

标签: ruby-on-rails-4 nested-attributes assign cocoon-gem

在我的应用程序中,我有模型Post& Slides&我有:

class Post < ActiveRecord::Base
   has_many :slides, inverse_of: :post
   accepts_nested_attributes_for :slides, reject_if: :all_blank, allow_destroy: true

一切正常,只有我需要(因为我的应用程序将如何工作),就是在创建slide时,我需要分配它是current_user或正在创建记录的用户。

我的user_id表中已经有slides并且:

class User < ActiveRecord::Base
  has_many :posts
  has_many :slide
end

class Slide < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

我的PostsController看起来像这样:

  def new
    @post = current_user.posts.build

    // This is for adding a slide without user needing to click on link_to_add_association when they enter new page/action
    @post.slides.build
  end


  def create
    @post = current_user.posts.build(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Was successfully created.' }
      else
        format.html { render :new }
      end
    end
  end

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

当我看到这个时,我看到了三种方法,但是既然你已经开始使用茧,我会放弃用户与用户之间的联系。幻灯片 - 因为它违反了良好的数据库实践(直到你达到了页面如此受欢迎的程度,你必须优化当然,但这样做会有所不同)。

你正在使用茧,但是你还没有充分利用这种关系的嵌套......

最佳做法是让茧的嵌套创造出两者兼而有之。而不是尝试分配给current_user,你可以调用类似的东西:

@slides = current_user.posts.find_first(param[:id]).slides

@slides保存所有结果,.Post.find(param[:id])找到current_user的特定帖子。

注意 :这不是最优化的方式&amp;我还没有对此进行测试,但它向您展示了一种可以考虑关系的方式。您需要点击rails console并运行一些测试,例如......

 (rails console)> @user = User.first

接下来,我们测试是否有可用的帖子,因为测试空白和放大器是令人沮丧的。没有得到结果......

(rails console)> @posts = @user.posts 

然后我们使用find方法&amp;我将使用Post.first来获取工作ID,您可以轻松地使用{&#34; 1&#34;或者你知道的任何号码都有效......

(rails console)> @post = @posts.find(Post.first)

最后,我们使用所有幻灯片来确保其有效的数据集

(rails console)> @post.slides

如果您想稍后特定的幻灯片&amp;拥有has_many关系,只需在find上标记.slides方法。

还有最后一件事 - 当你在那里说明你需要current_user相关时,你可以使用model.rb中的一个条目来创建一个方法或范围来获取数据&amp;允许您更轻松地将其链接到current_user&amp;如果性能问题,甚至可以使用.where方法删除一些定向SQL查询以提取该信息。

我在那里发现了第二个优化......如果一切正常 - 不要担心这个!

并且不要忘记strong_parameters嵌套来完全做到这一点...... Strong Param white listing

Basic format ... `.permit(:id, :something, slide_attributes: [:id, :name, :whatever, :_destroy])

答案 1 :(得分:1)

有两种方法可以实现这一目标:

第一个选项:保存幻灯片时,请填写用户ID,但这会很快变得非常混乱。您可以在before_save的模型中执行此操作,但是您如何知道当前用户ID?或者在控制器中执行此操作,并在保存/保存之后更改用户ID (如果未设置)。

但是,有一个更简单的选项:)使用:wrap_objectsee doc)的link_to_add_association选项,您可以预填表格中的user_id!如下所示:

= link_to_add_association ('add slide', @form_obj, :slides,
      wrap_object: Proc.new {|slide| slide.user_id = current_user.id; slide })

要完全正确,您还必须更改new方法,如下所示

@post.slides.build(user_id: current_user.id)

然后,当然,我们必须将user_id添加到表单中,作为隐藏字段,以便将其发送回控制器,并且不要忘记修复强参数子句以允许设置{ {1}}以及:)