Reputation: 24915
I saw a feature in an app that I'd like to be able to implement. The app has several resources - photos, articles etc.. In the nav bar next to the photos and articles tabs there were two buttons - organization and personal. When one clicks on the organization button if they then click on the photos or articles, they get a list of all photos and articles that belong to the members of their organization. If they clicked on the personal button and after that they click on photos or articles, they get lists of only their personal photos and articles, omitting the resources that belong to the other members of their organization. So I wonder how this state is kept between requests.
I imagine that one way would be to constantly pass a variable between the views and the controller and based on that variable to list a particular resource. Or maybe save the state in the session (though I suppose this should be done as a last resort). Another way would be to use a decorator like draper
, but I am kind of confused about the specifics of implementing this. I would be very grateful if somebody points me to an article or to a tutorial that shows how to implement such a feature or just provides an overview of the steps.
To be clear, one again: there are links to index different resources, but based on a parameter the index action of the respective controller returns different results. Something like:
def index
if params[:type] == 'organization'
@photos = Organization.find_by(id: params[:organization][:id]).photos
else
@photos = User.find_by(id: params[:user][:id]).photos
end
end
The question is - how do I pass the type
parameter - hard code it in the path helpers and have different views with different values for that parameter or is there a better way?
This is the relationship of my models:
class User < ActiveRecord::Base
belongs_to :organization,
inverse_of: :members
has_many :photos,
inverse_of: :owner,
foreign_key: :owner_id,
dependent: :destroy
...
end
class Photo < ActiveRecord::Base
belongs_to :owner,
class_name: User,
inverse_of: :photos
belongs_to :organization,
inverse_of: :photos
...
end
class Organization < ActiveRecord::Base
has_many :members,
class_name: User,
inverse_of: :organization,
dependent: :destroy
has_many :photos,
inverse_of: :organization,
dependent: :destroy
...
end
Upvotes: 0
Views: 116
Reputation: 433
By Reloading the Page with URL Parameters
I had a similar issue and there's a couple different ways to pass parameters depending on what you want. I actually just went with passing them through the url. If you append ?type=organization
to your url, you will get an additional key-value pair in your params, 'type' => 'organization'
and you can just use that. If you want to go to this URL through a link, you can just do link_to photos_path + "?type=organization"
. I ended up using javascript since I wanted something other than a link. Whatever your html element is, give it the attribute onclick=changeParam()
and then define that function in your javascript.
function changeParam() {
window.location.search = "?type=organization"
}
That will automatically reload the same page with that parameter. If you want more than one, append ¶m2=value2
to what you have so far.
Through AJAX
You can also use AJAX to pass parameters if you don't want a full refresh of the page. If you know how to use AJAX already, just use the data option:
$.ajax({
type: "GET",
url: "/photos",
data: { type : organization, param2 : value2 }
})
In this case, your params are sent though data. If you want to know more about AJAX and how to use that, let me know and I will update my answer with more details. It's pretty confusing in Rails and there isn't good documentation, so I'll add what I know if you want.
Upvotes: 1
Reputation: 1447
it can be solved on many different ways, but for example, if I understood you, one of them is that the resources photos, articles etc.. have one field which can be 'organization' or 'personal'. After that by clicking on this in application, you can filter resources (articles, photos,...) by that field.
Everything depends on situation, maybe another solution will be to create totally separated module where you gonna store things like organization, personal etc. This is better if you want to extend latter that and next to organization and personal add something else.
As I said, everything depends on situation and project.
additional:
ok, from your example I can see that by clicking on, for example, user link, you will have user id. Therefore, you can easily show all photos of that user:
# params[id] - user id which is got by clicking
user = User.find(params[id])
@photos = user.photos
Upvotes: 0