Pergunta

Eu tenho uma ação de criar que está a tentar criar uma avaliação e um programa de uma só vez:

  def create
    @rating = current_user.ratings.create(params[:rating])
    @rating.create_programme(params[:programme])
    redirect_to ratings_path
  end

Neste código, a classificação pertence a um usuário e um programa e um usuário

  has_many :ratings
  has_many :programmes, :through => :ratings

e um programa

  has_many :users, :through => :ratings
  has_many :ratings

Quando eu chamar a ação acima na RatingsController criar, o Programa não está sendo salvo como sendo de propriedade do @rating por algum motivo. Então, se eu chamar, por exemplo:

rating.programme.channel 

em uma classificação em um ponto de vista, ele me diz que o programa é um objeto nulo. No entanto, o programa foi salvo bem - é apenas a associação que não tenha sido salvo. Eu tenho certeza que é uma coisa muito básica aqui, mas eu não consigo entender. Alguém pode me apontar na direção certa?

graças, a

Foi útil?

Solução

Em resposta à sua pergunta para ajudar a tornar o código mais limpo:

def create
  @rating = Rating.new(params[:rating])
  @rating.user      = curent_user
  @rating.programme = Programme.find_or_create_by_title(params[:programme])
  @rating.save

  redirect_to ratings_path
end

Primeiro de tudo você chamar find_or_create para um título e, em seguida, salvá-lo, mas o registro vai aleady ser criado lá para o salvamento não faz nada em tudo. Em segundo lugar, enquanto os proxies de associação são legais para criar facilmente objetos ralated, eles podem ficar muito peludo em um relacionamento mais comlex como você tem aqui e tornar o código mais difícil de ler.

Assim, em vez de usar os proxies de associação para criar registros, atribuição direta seria melhor. É mais fácil dizer em poucas palavras exatamente o que está acontecendo e onde a informação está vindo, e não precisa de uma chamada merge feia lá dentro. É um pouco mais, mas eu pensa que a sua muito mais fácil de entender à primeira vista.

Finalmente, você provavelmente não precisa @programme como uma variável sozinha instância posição desde que você terá acesso fácil a esse objeto de @rating.programme em seus pontos de vista. Na maioria dos casos, é melhor passar por alguns variável de instância quanto possível, especialmente quando os objetos têm uma relação direta facilmente acessível. Sua especialmente verdadeiro no caso becuase você não está prestando um modelo em tudo.

Outras dicas

Seu código parece certo. Tente isto. Imediatamente depois de bater esta criar a ação de ir para dentro de você script / console e ver o que está acontecendo. Tipo:

Rating.last

Ele deve retornar a classificação que acabou de ser criado. Procure user_id e programme_id na saída e ver se eles estão definidos. Se eles são, então, você tem um outro lugar bug. Talvez você não está olhando para a classificação que você pensa que é ou algo assim.

Bem, você está tentando criar o pai da criança (classificações pertence Programa, certo?). Eu não acho que funciona.

Programme.ratings.create iria funcionar.

Eu tenho o ok trabalhando ação criar com o seguinte. Apreciaria se alguém poderia et-me saber se há uma maneira mais elegante de chegar a este trabalho:)

  def create
    @programme = Programme.find_or_create_by_title(params[:programme])
    @programme.save
    @rating = current_user.ratings.create!(params[:rating].merge(:programme_id => @programme.id))
    redirect_to ratings_path
  end

andy

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top