ActiveRecord关联仅在控制台中工作

时间:2014-10-30 01:46:48

标签: ruby-on-rails activerecord

我有一个User模型和一个ArtworkIteration模型。用户可以创建ArtworkIterations。

我的用户模型有很多artwork_iterations

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  has_many :artwork_iterations
end

我的artwork_iterations属于用户

class ArtworkIteration < ActiveRecord::Base
  belongs_to :user
end

这是将user_id外键添加到我的artwork_iteration模型的迁移

class AddUserIdToArtworkIterations < ActiveRecord::Migration
  def change
    add_column :artwork_iterations, :user_id, :integer
    add_index :artwork_iterations, :user_id
  end
end

当我在rails控制台中创建artwork_iteration时,它可以工作:

> @art = ArtworkIteration.create(user_id: User.last.id)
> @art.user
# Successfully returns the last user

但是当我在登录时通过我的网站创建artwork_iteration时,artwork_iteration.user为空。

为了解决这个问题,我在表单中添加了一个隐藏字段:

<%= f.hidden_field :user_id, value: "#{current_user.id}" %>

但这看起来很丑陋而且非常不安全。 (任何用户都可以检查元素并更改此值,使他们能够以不同的用户身份创建artwork_iterations)。

1 个答案:

答案 0 :(得分:2)

你可能知道答案而没有意识到这一点。我们需要最有可能看到您的控制器和路由,但是,在控制台中您可以清楚地分配user_id。在您的网站上,你显然不是。如果您在路线中的用户下嵌套了artwork_iterations,则必须在控制器中添加一个用于new和create的内容,如果您没有,则必须拥有另一个。

如果您是嵌套的,则在artwork_iterations控制器的顶部需要以下before_action:

before_action :get_user

然后在底部你需要这个私人方法:

def get_user
  @user = User.find(params[:user_id]) # (or current_user as you seem to have that helper)
end

这将传递localhost / user / 1 / artworkiterations / new页面的参数,以便用户匹配登录用户。如果您有Devise或者&#34; current_user&#34;你可以在这里使用current_user的方法。

我会假设你已经嵌套了它,但无论如何,你必须实际声明用户是谁,并在artwork_iterations控制器中创建动作。这样:

def new
  @artworkiteration = @user.artwork_iterations.build
end

这样的事可能对你有用。