Находит в Rails 3 и ActiveRelation - PullRequest
1 голос
/ 28 мая 2010

Я пытаюсь понять новый движок арлов в Rails 3, и у меня есть вопрос.

У меня есть две модели, Пользователь и Задача

class User < ActiveRecord::Base
  has_many :tasks
end

class Task < ActiveRecord::Base
  belongs_to :user
end

вот мои маршруты для обозначения отношения:

resources :users do
  resources :tasks
end

и вот мой контроллер задач:

class TasksController < ApplicationController
  before_filter :load_user

  def new
    @task = @user.tasks.new
  end

  private

  def load_user
    @user = User.where(:id => params[:user_id])
  end
end

Проблема в том, что я получаю следующую ошибку при попытке вызвать новое действие:

NoMethodError: undefined method `tasks' for #<ActiveRecord::Relation:0x3dc2488>

Я уверен, что моя проблема с новым движком arel, кто-нибудь понимает, что я делаю неправильно?

Извините, ребята, вот мой файл schema.db:

ActiveRecord::Schema.define(:version => 20100525021007) do

create_table "tasks", :force => true do |t|
  t.string   "name"
  t.integer  "estimated_time"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.integer  "user_id"
end

create_table "users", :force => true do |t|
  t.string   "email",                               :default => "", :null => false
  t.string   "encrypted_password",   :limit => 128, :default => "", :null => false
  t.string   "password_salt",                       :default => "", :null => false
  t.string   "reset_password_token"
  t.string   "remember_token"
  t.datetime "remember_created_at"
  t.integer  "sign_in_count",                       :default => 0
  t.datetime "current_sign_in_at"
  t.datetime "last_sign_in_at"
  t.string   "current_sign_in_ip"
  t.string   "last_sign_in_ip"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "username"
end

add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name =>       "index_users_on_reset_password_token", :unique => true
add_index "users", ["username"], :name => "index_users_on_username", :unique => true

end

Ответы [ 4 ]

2 голосов
/ 28 мая 2010

Я верю, что вы хотите:

def load_user
  @user = User.where(:id => params[:user_id]).first
end

Пока вы не попросите запись, она останется в отношениях.


Но find(params[:user_id]) все равно будет работать и вернет запись.

1 голос
/ 28 мая 2010

Работает ли это, если вы измените метод load_user, как показано ниже?

def load_user
  @user = User.find(params[:user_id])
end

Кроме того, я думаю, что вам может потребоваться изменить действие new на:

def new
  @task = @user.tasks.build
end
0 голосов
/ 30 мая 2010

Это на самом деле довольно просто. Вот один из методов ...

  def new
    @task = @user.tasks.new 
  end

  private

  def load_user
    # you must call a non-deferred operator to actually return 
    # the tuple that is connected to your tasks
    @user = User.where(:id => params[:user_id]).first
  end

Обязательно ознакомьтесь с семью частями обучения, которые я делаю по Active Relation. Первый эпизод поможет вам понять, в чем ваша ошибка была более понятной. http://Innovative -Studios.com / # пилот

find () НЕ считается устаревшей в некоторых случаях, как указано выше. Я бы ограничил использование find () для атомарных значений (где вы ищете определенный элемент / индекс). Все, что может быть основано на коллекции, я бы придерживался обертки предложения Where (ограничений) в ActiveRecord for Arel.

0 голосов
/ 29 мая 2010

Не путайте интерфейс гема Arel с новым интерфейсом запросов ActiveRecord. Синтаксис, описанный здесь, не будет работать: http://github.com/brynary/arel

ActiveRecord использует Arel под капотом, но создает свой собственный API-подобный API. Вот краткий взгляд на новый интерфейс запросов ActiveRecord: http://m.onkey.org/2010/1/22/active-record-query-interface

...