【问题标题】:Rails Associations: Going from has_many to has_oneRails 关联:从 has_many 到 has_one
【发布时间】:2014-03-31 11:20:19
【问题描述】:

我还是 Rails 的新手,正在尝试弄清楚如何将模型与用户关联为 has_one。

最初的设置是假设我的用户会有很多财务状况。现在,我需要对其进行更改,以便用户拥有一个财务。

财务模型:

class Finance < ActiveRecord::Base
    belongs_to :user
    validates :age, presence: true
    validates :zip, presence: true
end

用户模型:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :finances
end

当我将 has_many :finances 更改为 has_one :finances 时,我的财务控制器抛出错误。

class FinancesController < ApplicationController    
  # GET /finances
  # GET /finances.json
  def index
    @finances = Finance.find_all_by_user_id current_user[:id] if current_user
  end

  # GET /finances/new
  def new
    @finance = current_user.finances.build
  end

  # GET /finances/1/edit
  def edit
  end

  # POST /finances
  # POST /finances.json
  def create
    @finance = current_user.finances.build(finance_params)

    respond_to do |format|
      if @finance.save
        format.html { redirect_to @finance, notice: 'Successfully created.' }
        format.json { render action: 'show', status: :created, location: @finance }
      else
        format.html { render action: 'new' }
        format.json { render json: @finance.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /finances/1
  # PATCH/PUT /finances/1.json
  def update
    respond_to do |format|
      if @finance.update(finance_params)
        format.html { redirect_to @finance, notice: 'Successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @finance.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /finances/1
  # DELETE /finances/1.json
  def destroy
    @finance.destroy
    respond_to do |format|
      format.html { redirect_to finances_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_finance
      @finance = Finance.find(params[:id])
    end

    def correct_user
        @finance = current_user.finances.find_by(id: params[:id])
        redirect_to root_path, notice: "Welcome to TrustRose" if @finance.nil?
    end
end

错误来了:

 @finance = current_user.finances.find_by(id: params[:id])

我相信这需要改变,但我不知道如何查询数据库以找到与用户关联的财务,因为用户只有一个。

【问题讨论】:

  • 你需要更新你的路线并将current_user.finances.find_by(..)改为current_user.finance

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

在您的routes.rb 中,将resources :finances 更改为resource :finance

然后,更改您的 User 模型

class User < ActiveRecord::Base
  ...

  has_one :finance
end

通过has_one 关联,您可以在控制器中使用@finance = current_user.finance

现在,使用以下方式在视图中显示它:

<%= @finance.age %>

希望有帮助吗?

【讨论】:

  • 这是否意味着我必须将现有的财务控制器重命名为财务控制器?在我的 routes.rb 中更改它不再允许我定期编辑我的财务(/finances/6/edit)
  • 不,您不必,也不应该重命名控制器文件。假设finance只能由当前用户编辑,你只需要用/finance/edit更改它
  • /finance/edit 给我:路由错误未初始化常量 FinanceController。 edit_finance_path GET /finance/:id/edit(.:format) 财务#edit
  • 再次检查您的路线,您是否正确更改了您的routes.rb?使用rake routes,你会发现一行edit_finance GET /finance/edit(.:format) finances#edit。如果路线正确,应该没问题。
  • 那里仍然有资源(复数)。知道了 - 非常感谢!
【解决方案2】:

您的问题与模型名称的 Active Record 复数有关:http://guides.rubyonrails.org/association_basics.html

试试这个:

@finance = current_user.finance

【讨论】:

  • 以前在视图中获取与用户关联的财务,我使用了这一行:。 has_one 关联将如何改变?
  • 你不会再为一堆财务问题而讨价还价了。所以你在区块内做了什么,即 ,你只做一次。所以放弃 .each 位:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
相关资源
最近更新 更多