Rails 3:a​​lias_method_chain首先设置特定属性

时间:2011-07-15 00:00:47

标签: ruby-on-rails ruby-on-rails-3 methods

当用户创建帖子时,我想首先设置user_id属性。我试图在arrtibutes方法上使用alias_method_chain来做到这一点。但我不确定这是否正确,因为我认为这个问题仍然存在。它是否正确?

编辑:

当我的用户创建帖子时,他们使用名为“artist_tokens”的虚拟属性将“艺术家”指定为属于每个帖子。我将关系存储在艺术家模型和artist_ids和post_ids的联合表中,称为artisanships。

我还想存储创建属于他们帖子的艺术家的user_id(我希望它在艺术家模型本身内),所以我在艺术家模型上有一个user_id列。< /强>

问题是当我为每个帖子创建艺术家并尝试插入帖子创建者的user_id时,user_id一直显示为NULL。这很可能是因为帖子的user_id属性尚未设置。

我想要解决这个问题,我需要首先设置帖子的user_id属性,然后让其他属性按原样设置。这是我找到alias_method_chain的地方。

post.rb

 attr_reader :artist_tokens

  def artist_tokens=(ids)
    ids.gsub!(/CREATE_(.+?)_END/) do
      Artist.create!(:name => $1, :user_id => self.user_id).id
    end
    self.artist_ids = ids.split(",")
  end


    def attributes_with_user_id_first=(attributes = {})
      if attributes.include?(:user_id)
        self.user_id = attributes.delete(:user_id)
      end
      self.attributes_without_user_id_first = attributes
    end
    alias_method_chain :attributes=, :user_id_first

编辑:

class ArtistsController < ApplicationController

  def index
    @artists = Artist.where("name like ?", "%#{params[:q]}%")
    results = @artists.map(&:attributes)
    results << {:name => "Add: #{params[:q]}", :id => "CREATE_#{params[:q]}_END"}

    respond_to do |format|
      format.html
      format.json { render :json => results }
    end
  end

1 个答案:

答案 0 :(得分:0)

在您的控制器中,为什么不这样做:

def create
  @post = Post.new :user_id => params[:post][:user_id]
  @post.update_attributes params[:post]
  ...
end

但在我看来,在对帖子进行验证后,而不是在第一次分配属性时创建艺术家记录会好得多。

修改

我会将此更改为这样的回调:

class Post < ActiveRecord::Base
  attr_accessor :author_tokens
  def artist_tokens=(tokens)
    @artist_tokens = tokens.split(',')
  end

  after_save :create_artists
  def create_artists
    @artist_tokens.each do |token|
      ...
    end
  end
end