Доступ принадлежит к данным в каждом цикле - PullRequest
0 голосов
/ 12 июня 2019

Ни один из смежных вопросов не позволил решить эту проблему, поэтому я пробую новый.

У меня есть модель Дома, например:

class House < ApplicationRecord
    belongs_to :user, touch: true
    belongs_to :rental
end

У меня есть модель аренды:

class Rental < ApplicationRecord
  has_one :house, dependent: :destroy
  belongs_to :user
end

Пользователь может создавать дома и аренду.При создании аренды пользователь может выбрать (с <%= f.select ..... %>) дом, который он ранее добавил к своей панели инструментов.

Вот форма для создания аренды:

<%= form_for @rental, url: {action: "create"}, class: "card card--light p-4" do |f| %>
            <div class="field-row flex flex-row align-center justify-center">
                <div class="field m-5">
                    <%= f.label :title, "Name your rental" %>
                    <%= f.text_field :title, class: "input" %>
                </div>
            </div>
            <div class="field-row flex flex-row align-center justify-center">
                <div class="field m-5">
                    <%= f.label :house_id, "Select a house" %>
                    <%= f.select :house_id, options_for_select(@houses.map { |h| [h.address, h.id] }), prompt: 'Select', class: 'input' %>
                </div>
            </div>
            <div class="actions m-5">
              <%= f.submit "Register my rental", class: "btn btn--primary btn-devise" %>
            </div>
        <% end %>

У меня также есть контроллер дома:

class HousesController < ApplicationController
    before_action :authenticate_user!
    layout 'dashboard'

    def index
        @houses = current_user.houses
    end

    def show
        @houses = current_user.houses
        @house = House.find(params[:id])
    end

    def new
        @houses = current_user.houses
        @house = House.new
    end

    def create
        @house = House.new(house_params)
        @house.user = current_user

        if @house.save
            redirect_to houses_path
        else
            redirect_to new_house_url
        end
    end

.....
end 

и контроллер аренды:

class RentalsController < ApplicationController
    before_action :authenticate_user!
    layout 'dashboard'

  def index
    @houses = current_user.houses
    @rentals = current_user.rentals # i have tried @rentals = current_user.rentals.includes(:house) but doesn't work
  end

  def show
    @rental = Rental.find(params[:id])
  end

  def new
    @houses = current_user.houses
    @rental = Rental.new
  end

  def create
    @rental = Rental.new(rental_params)
    @rental.user = current_user

    if @rental.save
        redirect_to rentals_path
    else
        redirect_to new_rental_url
    end
  end

.........

end

Наконец, я пытаюсь получить доступ к данным Дома через Rental, на мой взгляд, в каждом цикле следующим образом:

<% @rentals.in_groups_of(3, false) do |rental_array| %>
   <% rental_array.each do |rent| %>
    <%= rent.house.address %>
        <%= link_to 'Edit my rental', edit_rental_path(rent) %>
        .....
   <% end %>
<% end %>

Это выдает мне это сообщение об ошибке: undefined method address 'для nil: NilClass`.

Вот что я делаю в консоли rails:

rental = Rental.last
Rental Load (0.2ms)  SELECT  "rentals".* FROM "rentals" ORDER BY "rentals"."id" DESC LIMIT $1  [["LIMIT", 1]]
 => #<Rental id: 8, house_id: 15, user_id: 1, created_at: "2019-06-12 09:24:52", updated_at: "2019-06-12 09:24:52", title: "My rental"> 

rental.bien
 House Load (0.4ms)  SELECT  "houses".* FROM "houses" WHERE "houses"."rental_id" = $1 LIMIT $2  [["rental_id", 8], ["LIMIT", 1]]
 => nil 

Я в замешательстве, потому что я думаю, что проблема исходит от формы (select), которая недействительно выбирая любой дом.Но с другой стороны, в консоли видно, что право аренды имеет house_id.Так что, похоже, на самом деле выбор дома.

Ответы [ 2 ]

0 голосов
/ 12 июня 2019

Ваша модель Rental, кажется, имеет атрибут house_id, но вы определяете Rental has_one :house.Вместо этого это должно было быть Rental belongs_to :house.

Трюк с has_one против belongs_to, где бы ни добавлялся атрибут house_id (или some_model_id), это то, где вы определяете belongs_to, и тогда другая модель будет has_one.В этом случае вы определили атрибут внешнего ключа house_id в модели Rental, затем модель Rental должна belongs_to :house, а затем House has_one :rental

0 голосов
/ 12 июня 2019

То, как вы хотите получить доступ к атрибутам, в порядке, но:

rent.house.address

сначала попытается получить доступ к атрибуту house объекта rent, и если в аренде нет домов, он вернет nil, а после этого попытается получить доступ к адресу ... nil, так что это ошибка. постарайтесь избегать такого типа вызовов, но если нет возможности прочитать об этом: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

и в этом случае:

rent&.house&.address

должно работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...