Ruby on Rails:棘手多对多关系不起作用

时间:2014-03-10 21:43:56

标签: activerecord ruby-on-rails-4

我正在我的应用程序中设计“列表”映射功能以进行转码。 这样我的mappins_list对象就指向一个source_list对象和一个target_list对象,两者都是一个实例values_list类。 该设计看起来很经典,但它的表现并不像预期的那样:

 <td><%= link_to @mappings_list.source_list.name, @mappings_list.source_list%>

提出

undefined method `source_list' for #<ActiveRecord::Relation::ActiveRecord_Relation_MappingsList:0x00000004217718>

在索引视图中。

(请注意,一条记录包含正确的属性,应该在那里显示)

以下是代码:

# == Schema Information
#
# Table name: values_lists
#
#  id            :integer          not null, primary key
#  playground_id :integer
#  code          :string(255)
#  name          :string(255)
#  description   :text
#  created_by    :string(255)
#  updated_by    :string(255)
#  owner_id      :integer
#  table_name    :string(255)
#  created_at    :datetime
#  updated_at    :datetime
#  software_id   :integer
#  software_name :string(255)
#



class ValuesList < ActiveRecord::Base

### scope
  scope :pgnd, ->(my_pgnd) { where "playground_id=?", my_pgnd }

### before filter
  before_create :set_code

### validation
    validates :code, length: { maximum: 100 }
    validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
    validates :description, length: { maximum: 1000 }
    validates :created_by , presence: true
    validates :updated_by, presence: true
    validates :playground_id, presence: true
    belongs_to :playground
    validates :playground, presence: true                       # validates that the playground exists
    belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"        # helps retrieving the owner name
    belongs_to :software, :class_name => "Parameter", :foreign_key => "software_id" # helps retrieving the software name
    has_many :values
    has_many :mappings_lists

### private functions definitions
  private

  ### before filters
    def set_code 
      self.code = name.gsub(/[^0-9A-Za-z]/, '_').upcase
    end 

end

# == Schema Information
#
# Table name: mappings_lists
#
#  id             :integer          not null, primary key
#  playground_id  :integer
#  code           :string(255)
#  name           :string(255)
#  description    :text
#  created_by     :string(255)
#  updated_by     :string(255)
#  owner_id       :integer
#  source_list_id :integer
#  target_list_id :integer
#  created_at     :datetime
#  updated_at     :datetime
#


class MappingsList < ActiveRecord::Base

### scope
  scope :pgnd, ->(my_pgnd) { where "playground_id=?", my_pgnd }

### before filter
  before_create :set_code

### validation
    validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
    validates :description, length: { maximum: 1000 }
    validates :created_by , presence: true
    validates :updated_by, presence: true
    validates :playground_id, presence: true
    belongs_to :playground
    validates :playground, presence: true                           # validates that the playground exists
    belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"            # helps retrieving the owner name
    belongs_to :source_list, :class_name => "ValuesList", :foreign_key => "source_list_id"  # helps retrieving the source list name
    belongs_to :target_list, :class_name => "ValuesList", :foreign_key => "target_list_id"  # helps retrieving the target list name
    has_many :mappings

### private functions definitions
  private

  ### before filters
    def set_code 
      self.code = "#{source_list.code}_TO_#{target_list.code}"
    end 

end

路由包含:

  resources :values_lists do
    resources :values
    resources :mappings_lists
  end

控制器在这里:

class MappingsListsController < ApplicationController
# Check for active session  
  before_action :signed_in_user

# Retrieve current current mapping
  before_action :set_mappings_list, only: [:show, :edit, :update, :destroy]

# Retrieve all lists of values
  before_action :set_values_lists

  # GET /mappings_list
  # GET /mappings_list.json
  def index
    @mappings_list = MappingsList.pgnd(current_playground).order("name")
  end

  # GET /mappings_list/1
  # GET /mappings_list/1.json
  def show
    ### Retrieved by Callback function
  end

  # GET /mappings_list/new
  def new
    @mappings_list = MappingsList.new
  end

  # GET /mappings_list/1/edit
  def edit
    ### Retrieved by Callback function
  end

  # POST /mappings_list
  # POST /mappings_list.json
  def create
    @mappings_list = MappingsList.new(mappings_list_params)
    @mappings_list.updated_by = current_user.login
    @mappings_list.created_by = current_user.login
    @mappings_list.playground_id = current_user.current_playground_id
    @mappings_list.owner_id = current_user.id

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

  # PATCH/PUT /mappings_list/1
  # PATCH/PUT /mappings_list/1.json
  def update
    ### Retrieved by Callback function
    @mappings_list.updated_by = current_user.login
    respond_to do |format|
      if @mappings_list.update(mappings_list_params)
        format.html { redirect_to @mappings_list, notice: 'List of mappings was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @mappings_list.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /mappings_list/1
  # DELETE /mappings_list/1.json
  def destroy
    ### Retrieved by Callback function
    @mappings_list.destroy
    respond_to do |format|
      format.html { redirect_to mappings_lists_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    # Check for active session
    def signed_in_user
      redirect_to signin_url, notice: "You must log in to access this page." unless signed_in?
    end

    def set_mappings_list
      @mappings_list = MappingsList.pgnd(current_playground).find(params[:id])
    end

    # retrieve the list of values lists
    def set_values_lists
      @lists_of_values = ValuesList.all
    end 

    # Never trust mappings from the scary internet, only allow the white list through.
    def mappings_list_params
      params.require(:mappings_list).permit(:name, :description, :source_list_id, :target_list_id)
    end
end

对values_list的双重引用是否会使我的应用程序陷入困境?

感谢您的帮助,

致以最诚挚的问候,

佛瑞德

2 个答案:

答案 0 :(得分:0)

在MappingsList&lt;类中ActiveRecord :: Base模型 你有属于source_list的MappingList。 我相信是倒退的:

class Order < ActiveRecord::Base belongs_to :customer end

@order = @customer.orders

答案 1 :(得分:0)

好的,我明白了!

在索引视图中,当我处理实例列表时,我无法引用一个实例变量,例如@mappings_list。

代码可以正常使用:

        <td><%= link_to mappings_list.source_list.name, mappings_list.source_list%>

作为RoR的初学者,我希望我的解释是正确的......

感谢您的帮助,

致以最诚挚的问候,

佛瑞德