简体   繁体   English

Rails 3:alias_method_chain 先设置特定属性

[英]Rails 3: alias_method_chain to set specific attribute first

When user's create a post I'd like to set the user_id attribute first.当用户创建帖子时,我想先设置 user_id 属性。 I'm trying to do this using alias_method_chain on the arrtibutes method.我正在尝试在 arrtibutes 方法上使用 alias_method_chain 来做到这一点。 But I'm not sure if this is right as the problem I thought this would fix is still occurring.但我不确定这是否正确,因为我认为可以解决的问题仍在发生。 Is this correct?这个对吗?

Edit:编辑:

When my users create a post they assign 'artist(s)' to belong to each post, using a virtual attribute called 'artist_tokens'.当我的用户创建帖子时,他们使用名为“artist_tokens”的虚拟属性将“艺术家”分配给每个帖子。 I store the relationships in an artist model and a joined table of artist_ids and post_ids called artisanships.我将关系存储在艺术家 model 和一个名为 artisanships 的艺术家 ID 和 post_id 的连接表中。

I'd like to to also store the user_id of whomever created the artist that belongs to their post (and I want it inside the artist model itself), so I have a user_id column on the artist model.我还想存储创建属于他们帖子的艺术家的用户 ID(我希望它在艺术家 model 本身内),所以我在艺术家 model 上有一个 user_id 列。

The problem is when I create the artist for each post and try to insert the user_id of the post creator, the user_id keeps showing as NULL.问题是当我为每个帖子创建艺术家并尝试插入帖子创建者的 user_id 时,user_id 一直显示为 NULL。 Which is highly likely because the post's user_id attribute hasn't been set yet.这很可能是因为帖子的 user_id 属性尚未设置。

I figured to get around this I needed to set the user_id attribute of the post first, then let the rest of the attributes be set as they normally are.我想解决这个问题,我需要先设置帖子的 user_id 属性,然后让属性的 rest 正常设置。 This is where I found alias_method_chain.这是我找到 alias_method_chain 的地方。

post.rb 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

EDIT:编辑:

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

In your controller, why not just do this:在您的 controller 中,为什么不这样做:

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

But it seems to me that it would be much better to create the artist records after you've done validation on the post rather than when you first assign the attribute.但在我看来,在您对帖子进行验证之后创建艺术家记录会比您第一次分配属性时要好得多。

EDIT编辑

I would change this to a callback like this:我会将其更改为这样的回调:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM