0

数時間試した後、データベースに保存できません。

コンテキストは次のとおりです。2つのタイプのユーザーがあります。1つは非常に基本的な情報[ユーザー名、電子メール、パスワード]のみが必要であり、もう1つは多くの情報[年齢、性別、都市など]が必要なユーザーです。 ]

テーブルに大量のNull値があるため、STIは使用しませんでした。そこで、ユーザーがプロファイル(プロファイルテーブル)を持っているか、タイプ[1または2]に依存しない、この3つのモードを作成しました。このプロファイルのフィールドは、このユーザーが住んでいる都市であり、 DB、都市テーブル

class User < ActiveRecord::Base
  has_one :profile
  has_one :city, through: :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
  belongs_to :city
  [...a bunch of fields here]
end

class City < ActiveRecord::Base
  has_many :profiles
  has_many :users, through: :profiles
end

Railsコンソールでそれらを操作すると、すべて問題なく動作します。

usr = User.new(name: "roxy", email: "roxy@example.me", password: "roxanna", password_confirmation: "roxanna", utype: 1)
cty = City.new(name: "Bucaramanga")
prf = Profile.new (rname: "Rosa Juliana Diaz del Castillo"...)
prf.city = cty
usr.profile = prf
usr.valid?
=> true
usr.save
=> true

しかし、アプリに保存しようとすると(モデルを表示)

<%= f.label :city, "En que ciudad te encuentras?"%>
<%= select_tag :city, options_from_collection_for_select(City.all, 'id', "name"),{:prompt => 'Selecciona tu ciudad'}%>

def new
  @profile = Profile.new
end

def create
  @profile = params[:profile]
  @city= City.find_by_id(params[:city].to_i)
  @profile.city = @city
end

このエラーが発生します:

undefined method `city=' for #<ActiveSupport::HashWithIndifferentAccess:0xa556fe0>

誰か助けてくれませんか?

更新 Davidが提案したように、createメソッドの最初の行にProfileオブジェクトを作成したので、コントローラーは次のようになります。

def create
  @profile = Profile.new(params[:profile])
  @city= City.find_by_id(params[:city].to_i)
  @profile.city = @city
  @usr = current_user
  if @usr.profile.exists? @profile
    @usr.errors.add(:profile, "is already assigned to this user") # or something to that effect
    render :new
  else 
   @usr.profile << @profile
   redirect_to root_path
  end
end

しかし、私は今このエラーを受け取っています

undefined method `exists?' for nil:NilClass

current_userは@current_userを返します

def current_user
  @current_user ||= User.find_by_remember_token(cookies[:remember_token])
end

教えていただけませんか、何が間違っているのですか?

4

3 に答える 3

1

私と同じように始めて、このステップで立ち往生しているすべての人にこれを書きたいと思います。

私は新しいプロジェクトを作成し、それで遊んで、自分が間違っていたことに気づかなければなりませんでした。Profilesテーブルに最後に追加したフィールドを検証していることがわかりました。

# education       :string(255)     not null

しかし、まだフォームに追加していなかったため、起動したエラーは次のとおりです。

Failed to save the new associated so_profile.

これで、このエラーが発生したかどうかがわかりました。スキーマを確認して、フォームにない可能性のあるNOT_NULLフィールドを探してください。また、すべてのモデル検証をコメントアウトして、機能した後、コメントを外してください。

だから、私の最終モデル:

class User < ActiveRecord::Base
  has_one :profile
  has_one :city, through: :profile
  attr_accessible :email, :name
end

class Profile < ActiveRecord::Base
  belongs_to :user
  belongs_to :city
  attr_accessible :age, :fcolor, :gender
end

class City < ActiveRecord::Base
  has_many :profiles
  has_many :users, through: :profiles
  attr_accessible :name
end

私のコントローラー:

class ProfilesController < ApplicationController
  def new
    @user = User.find_by_id(params[:id])
    @profile = Profile.new
  end

  def create
    @profile = Profile.new(params[:profile])
    city = City.find_by_id(params[:city])
    @profile.city = city
    @user = User.find_by_id(params[:userid])
    @user.profile = @profile
    if @user.save
      flash[:success] =  "Guardado"
      redirect_to profile_path(id: @user.id)
    end
  end

  def show
   @user = User.find(params[:id])
  end  
end

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:success] =  "Registrado!"
      redirect_to new_profile_path(id: @user.id)
    else
      flash[:error] =  "No Registrado :("
      redirect_to new
    end
  end

  def show
    @user = User.find_by_id(params[:id])
  end
end

実際のアプリでは、セッションを存続させるためにCookieなどを使用する必要があります。したがって、user_idを取得する場所からuser_tokenを使用する必要がありますが、関連付けを操作するために機能します。

ビュー:

プロファイル/new.html.erb

<%= @user.name %>
<%= form_for @profile, url: {action: :create, userid: @user.id } do |f| %>
<%= f.label :age, "Edad" %>
<%= f.text_field :age%> <br />

<%= label :city, "Ciudad"%>
<%= select_tag :city, options_from_collection_for_select(City.all, 'id', 'name')%>

<%= f.submit %>
<% end %>

プロファイル/show.html.erb

Hello <%= @user.name %><br />
Tu edad es: <%= @user.profile.age %><br />
Vives en <%= @user.profile.city.name%>

users / new.html.erb

<%= form_for @user do |f|%>
<%= f.label :name, "Nombre"%>
<%= f.text_field :name, size: 20, placeholder: "Escribe tu nombre aqui" %><br />

<%= f.label :email, "Email"%>
<%= f.text_field :email, size: 20, placeholder: "Escribe tu email aqui" %><br />

<%= f.submit "Sign me up!"%>

users / show.html.erb

Name: <%= @user.name %><br />
Email: <%= @user.email %>

以上です!

乾杯。

于 2012-07-27T04:29:35.380 に答える
0

エラーメッセージの読み方を学びましょう。問題は、メソッドの最初の行に実際に新しいProfileオブジェクトを作成しなかったため、@profileがハッシュであるということですcreate

于 2012-07-26T15:06:56.723 に答える
-1

正しいと思います

@so_profile.City 

いいえ

@so_profile.city  

クラス名がCityだから

于 2012-07-26T15:01:56.023 に答える