Как перебрать все доступные массивы в коде Ruby - PullRequest
0 голосов
/ 20 февраля 2012

Я пытаюсь создать панель мониторинга, где пользователи (модель пользователя), которые щелкнули «посещение» (которое можно пометить) на событие (модель события), которое связано с коллекцией (модель коллекции), смогут видеть для каких событий они собираются.

Мой вопрос, однако, заключается в том, как просто пройтись по всем возможным массивам, чтобы я мог получить все связанные идентификаторы для событий, которые пользователь щелкнул, «посещая».

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

user_statistics.html.erb

<div class="span3 events">
    <h3>Events</h3>
    <% if @events.empty? %>
        <p>You are currently not attending any events.</p>
    <% else %>
        <p>You are attending: <b><%= pluralize(@events.count, "event") %></b></p>
        <p>Event 1: <%= @event1_name %> on Date: <%= @event1.date %> at Time:<%= @event1.time %></p>
    <% end %>
</div>

pages_controller.rb

    def home
    @title = "Title"
    @user = current_user
    if current_user
        @post = Post.new
        @feed_items = current_user.feed
        @user_following = @user.following
        @user_followers = @user.followers
        @events = @user.flaggings.with_flag(:attending)
        @event1 = Event.find(@events[0].flaggable_id)
        @event1_name = Collection.find(@event1.collection_id).name
    end
end

Я установил для массива @ event1 значение 0, чтобы получить доступ к первому флагу для «посещения», а затем получил flaggable_id, поэтому у меня есть идентификатор для вызова коллекции.

Моя проблема в том, что если у меня есть несколько событий, как я могу пройти по всем массивам, чтобы гарантировать, что я смогу извлечь все Коллекции?

Для первого пользователя, который нажал «посещать» 2 события, это данные:

в IRB, для User.first, кто посещает 2 события

  User Load (0.3ms)  SELECT "users".* FROM "users" LIMIT 1
  MakeFlaggable::Flagging Load (0.4ms)  SELECT "flaggings".* FROM "flaggings" WHERE 
"flaggings"."flagger_id" = 1 AND "flaggings"."flagger_type" = 'User' AND 
"flaggings"."flag" = 'attending'
 [#<MakeFlaggable::Flagging id: 16, flaggable_type: "Event", flaggable_id: 3, 
flagger_type: "User", flagger_id: 1, flag: "attending", created_at: "2012-02-20 09:26:36", 
updated_at: "2012-02-20 09:26:36">, #<MakeFlaggable::Flagging id: 18, flaggable_type: 
"Event", flaggable_id: 4, flagger_type: "User", flagger_id: 1, flag: "attending", 
created_at: "2012-02-20 10:38:00", updated_at: "2012-02-20 10:38:00">] 

Вы можете видеть, что пользователь пометил «посещение» для 2 событий, которые хранятся в массивах. Следовательно, если у меня есть 2 события, в идеале я бы хотел пройти через цикл таким образом, чтобы у меня было 2 массива.

Я нахожу это довольно запутанным для реализации этого ... любая помощь будет высоко ценится!

код user.rb

Class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation, :user_bio, 
                :shop, :cover_photo, :avatar, :remote_image_url
has_secure_password
mount_uploader :cover_photo, ImageUploader
mount_uploader :avatar, ImageUploader

make_flagger

scope :shop, where(shop: true)

has_many :posts,                    dependent: :destroy
has_many :relationships,            dependent: :destroy,
                                    foreign_key: "follower_id"
has_many :reverse_relationships,    dependent: :destroy,
                                    foreign_key: "followed_id",
                                    class_name: "Relationship"

has_many :following, through: :relationships, source: :followed 
has_many :followers, through: :reverse_relationships, source: :follower 

has_many :collections,              dependent: :destroy 
...
end

collection.rb частичный код

class Collection < ActiveRecord::Base
attr_accessible :name, :description, :image, :remote_image_url
belongs_to :user
has_many :products,     dependent: :destroy
has_many :events,       dependent: :destroy
mount_uploader :image, ImageUploader
make_flaggable :like
...
end

events.rb частичный код

class Event < ActiveRecord::Base
attr_accessible :date, :time, :description
belongs_to :collections
make_flaggable :attending
...
end

Ответы [ 3 ]

0 голосов
/ 20 февраля 2012

Является ли flaggable драгоценным камнем или вы написали его как полиморфный класс?

Эта строка немного противная (извините):

@events = @user.flaggings.with_flag(:attending)

Переменная @events не содержит события - она ​​содержит коллекцию флагов. По соглашению об именах это явно плохо.

Кроме того, эта строка, вероятно, является избыточной, если вы установили (или использовали гем) для флагманских полиморфных отношений:

@event1 = Event.find(@events[0].flaggable_id)
#This could be rewritten as:
@event1 = @events.first.flaggable

Или, что еще лучше, объединить две предыдущие строки в:

#@events = @user.flaggings.with_flag(:attending)
#@event1 = Event.find(@events[0].flaggable_id)
#becomes:

flaggings = @user.flaggings.with_flag(:attending)
@events = flaggings.map(&:flaggable)

@ jxpx777 очень хорошо описывает именованные области видимости и ассоциации hmt. Это, вероятно, путь вперед. Вы могли бы сделать что-то вроде этого:

Class User < AR...

has_many :attendances, :class => 'Flagging', :conditions => {:flag => 'attending'} #You might need to add :type => "Event" if you use flaggings elsewhere...

has_many :events_attending, :class => 'Event', :through => :attendances, :source => :flaggable_id #You'll probably have to change a lot of these variable names - I can't see the rest of your source code...

Это даст вам возможность просто:

@events = @user.events_attending.include(:collection)

Предостережение - ни один из этих кодов не тестировался - все это с моей головы, но оно должно указывать вам в правильном направлении, по крайней мере,

0 голосов
/ 21 февраля 2012

Хорошо, мне удалось решить свою проблему, хотя и очень грязно ...

pages_controller.rb

    def home
    @title = "Simplifying and socializing online shopping - Ruuva"
    @user = current_user
    if current_user
        @post = Post.new
        @feed_items = current_user.feed

        @user_following = @user.following
        @user_followers = @user.followers

        @events_attending = @user.flaggings.with_flag(:attending)
    end
end

_user_statistics.html.erb частичный

        <h3>Events</h3>
    <% if @events_attending.empty? %>
        <p>You are currently not attending any events.</p>
    <% else %>
        <p>You are attending these events:</p>
        <ol>
            <% @events_attending.each do |e| %>
                    <% unless Event.find_by_id(e.flaggable_id).nil? %>                      
                    <li>
                        Collection: <%= link_to Collection.find(Event.find(e.flaggable_id).collection_id).name, event_path(e.flaggable_id) %>
                        <br>happening on: <%= Event.find(e.flaggable_id).date %> at <%= Event.find(e.flaggable_id).time %>
                    </li>
                    <% end %>
            <% end %>
        </ol>
    <% end %>

Я почти уверен, что код очень плохой, и я действительно использовал несколько «горячих» проблем, которые укусят меня в будущем ... но MVP - это MVP. Спасибо, ребята за помощь, хотя! :)

0 голосов
/ 20 февраля 2012

Это не на 100% ясно из вашего поста, но звучит так, как будто вам нужна именованная область действия для событий, где установлен флаг присутствия и ассоциация has_many: through , чтобы позволить У пользователя есть события. С этими двумя битами вы могли бы сделать что-то вроде:

User.first.events.attending

и AREL позаботится о том, чтобы все это было в хорошем быстром запросе для вас.

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