Ruby on Rails first_or_create嵌套模型

时间:2017-02-20 11:23:39

标签: ruby-on-rails validation

放置模型:

class Place < ApplicationRecord
  has_many :post_places, dependent: :destroy
  has_many :posts, through: :post_places
end

发布模型:

class Post < ApplicationRecord
  has_many :post_places, dependent: :destroy
  has_many :places, through: :post_places, dependent: :destroy

  accepts_nested_attributes_for :places,
                                :allow_destroy => true,
                                :reject_if     => :all_blank

end

发布创建:

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

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

Post Params:

def post_params
  params.require(:post).permit(:title, :description, :user_id, places_attributes: [:id, :title, :latitude, :longitude, :_destroy])
end

当注册一个新帖子时,我希望它不会重新注册并使用该ID,如果它已在数据库中注册。我发现此代码执行此操作,但它不接受它,因为它是一个嵌套属性。

我使用的代码创建:

@place = Place.where(latitude: place_params[:latitude], longitude: place_params[:longitude]).first_or_create do |place|
  place.attributes = place_params
end

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

根据你的描述说

“如果提交现有地点,我想与帖子相关联,但如果不存在则创建新地点。”

你的要求是这样的,检查这个答案,如果你需要这样的话,请给我打电话。这样我们就可以继续前进了。

@place = Place.where(latitude: place_params[:latitude], longitude: place_params[:longitude])

if @place.present? // if place exist
    @post.places << @place // push that to existing post
else
    @place = Place.new(latitude: place_params[:latitude], longitude: place_params[:longitude]) 
    if @place.save // else create a place
        @post.places << @place // push that to post
    end   
end    

答案 1 :(得分:0)

你可能需要调整一下,我认为是这样的

  #will yield the place, or a new one will be initialized                    
  @place = Place.where(latitude: place_params[:latitude], longitude: place_params[:longitude]).first_or_initialize(place_params)
  #find associated post
  @post = Post.find(post_params)
  #add to collection
  @place.posts << @post

  if @place.valid?
    @place.save
  end

如果你想要反过来

  @post.places << @place

我不确定'Post.find',我认为你在你的参数中缺少Post.id