I added show_change_link = True to an inline in Django 1.8, but the links are not added to the inlined items. Every model in the app is registered in the admin. Am I missing something? I can only find one sentence regarding this feature in the documentation.
EDIT:
class TheInline(admin.TabularInline):
model = TheModel
readonly_fields = ['timestamp']
extra = 0
show_change_link = True
I am not using any custom admin like grappelli, and all the models in the app are registered in the admin.
Got it! A while back I made a customized admin template for another view, and I didn't realize affected everything in the admin - just wasn't thinking. You got me going in the right direction OriolJ. Thanks!
I had this trouble without customized admin templates, but i realized that i didn't have the another model registered in the admin. So, don't forget to register the inline model to the admin.
Related
I have an active admin page called vendor that has a list of user in my model written as:
has_many :users do
def staff_users
where('staff_user' = true)
end
In my vendor active admin form I need to make an autocomplete search for users that I can add to my staff_users (I have the function already working).
I just need to get the available list of users as a collection on my front end.
I've seen this gem select2 from activeadminaddons and installed it using gem install activeadmin_addons. I was trying to use it, however I'm having a problem understanding what is the url for.
Is it correct that I need to create a method on my vendors_controller that can be mapped in my routes.rb that will return all User?
If what I understood is not what it's supposed to do, can someone please explain to me what and how to connect the url param in active admin select2 activeadminaddons.
Any other ideas too? Maybe without the use of this gem, there's a simple solution I can integrate what I need in active admin?
Thanks!
Try running rake routes and find the collection_url for your Vendor model. I guess it will be something like: admin_vendors_path. This route has been dynamically created by registering your model through ActiveAdmin.
Maybe try reading more at: https://github.com/platanus/activeadmin_addons/blob/master/docs/select2_search.md
I am fairly new to rails and am just getting into using cool gems and APIs. I have been made aware that this community values the contents of questions and answers, or it is expected that they are constructed in a specific way. The short way to ask my question and the long way are provided. Please let me know which is preferred here! It is a real question though!
SHORT VERSION
I have a users_controller and User object with a username attribute in a rails app. How do I create global variables for these users that is dynamically based on their username? Example: I want with my user (id = 1, first_name = "Rob", username = "rocky") to be callable as #rocky. So what would go below in my Users_controller that is based on the first code line below working for me in terminal:
#rocky = User.find_by_username("rocky")
WHATGOESHERE = User.find_by_username(params[:username]}
or should I be using this in some shape or form in place of params[:username]
#"#{user.username}"
Below is the longer version of my question. It is more detailed and follows more closely how I approached the issue. The first one... that I wrote second, is more concise but that's not always what people want... please let me know which is preferred on this site. Thanks!!
LONG VERSION
I need some clarity on a few things. I am using a gem called "has_friendship" to create friendships between my users (link to gem- https://github.com/sungwoncho/has_friendship ).
First, this is the documentations example of how to request a friendship, starting with the creation of the users.
#mac = User.create(name: "Mac")
#dee = User.create(name: "Dee")
# #mac sends a friend request to #dee
#mac.friend_request(#dee)
This is where I first became confused. My users don't have a "name" field. But that's ok. I managed to figure out that I just need to assign my created users global variables as they do... since my users will be interacting with each other behind their "username" attribute. So first question, How do I assign a dynamic variable name to each user? In the documentation, they are hard-coding in the names "Mac" and "Dee." I need to have this global variable be created upon the creation of the object.. So my plan is to do this in the controller. Here I am already defining #users and #user in users#show
#users = User.all
#user = User.includes(:wallet).find_by_id(params[:id])
So my thought process is that the left side of the equation should be the name of what you're naming and the right side is what that name is referring to. So for the right side, I'd think to put
User.find_by_username(params[:username])
as when in the terminal, if I replace the content in parenthesis with an actual username in quotes, it brings up that user's info. So how do I write the left side. I would think the left side is something like this:
#"#{params[:username]}"
So in full I currently have the following in my users_controller to assign global variables to my users based on their username atttribute...
#"#{params[:username]}" = User.find_by_username(params[:username])
This, especially the left side, does not look at all right to me. So I've looked around on google a bunch and the only other thing I can find that looks like the right way to do this is by using "instance_variable_set" but everything I've looked at doesn't make total sense for my situation... (as usual.. ha)
Ok what I get to know from your question is you want to use friend_request method to associate two users.
For this, you don't need to assign them to any variables. You can directly do this by something like this -
Suppose there are two user's
id=1 first_name='Rocky' username='rocky'
id=2 first_name='Nimish' username='nimish'
User.find_by(username: 'rocky').friend_request(User.find_by(username: 'nimish'))
OR
User.find_by_username('rocky').friend_request(User.find_by_username( 'nimish'))
Also, If you want to assign them to instance variable then it is not necessary to create an instance variable corresponding to the username value
You can simply assign them to #user and #requested_user and then
#user.friend_request(#requested_user)
Working through authentication in RailsCasts, there was one where I didn't understand something completely fundamental and important (it's pro, sorry - you need to be subscribed to access it).
He creates a user model with an email and encrypted password (has_secure_password).
Then he makes a new controller called Sessions, and declares it as a resource in the config. i.e.
resources :sessions
Then, inside the sessions controller, he defines the create method like this:
user = find user and authenticate
if user
session[:user_id] = user.id
else ...
But sessions as a model doesn't exist. For instance, if I open up my console and write
sessions[:user_id] = "hello"
it throws. Does anyone have an explanation or a link to this very basic concept that I'm missing?
Thanks!
Edit: Thanks Sanfor. Typo fixed, also for markup plus most importantly an answer!
I suppose you have copied the session as sessions in your question, is that correct? The screen cast is revised, so you'd need to be subscribed what I'm not nowadays so can't confirm it more than what comments say.
Now to the actual answer, the session is Rails internal reference to the actual session on hand as described here and for that reason you can't see the model for it created.
Simplistic explanation:
session is just a hash and stored as a cookie. (Unless you specifically instructed Rails to store it in the database). Models are typically ActiveRecord based and have some behavior.
You can add to it by simply
session[:some_thing] = "Info for session"
session[:store_this_too] = "Some other info to track for this session"
The session hash is created by the controller-related class/modules and rails console doesn't load them. Therefore, it is not available in the console.
Here's a pretty old Railscasts which explains a bit more. And this which takes the model-based approach. Bear in mind they are from the old days.
I am building a Rails app that is intended to be eventually used by non-technical people. It consists of a few pages with blocks of text and a special page with interactive canvas drawings.
I want to allow them to easily edit any piece of text contained in the application. What are the best ways to achieve that? Currently, text is written in the different views of the application, which does not allow them to edit it without having to connect via FTP or similar and search for the right file.
I am thinking of three solutions:
Store all blocks of text in the database. On each page, fetch the requires blocks and insert them before rendering. Build a page that lists all blocks in the database in editable areas with a save button.
Store all blocks of text in a json file. Create a model that can read the file and fetch the blocks required by the views. Build a page that lets you edit each block and save it in the file.
Create some kind of password-protected admin interface that fetches all file in the views directory, use regexp to find blocks of text and allow the users to edit each block and save.
From my point of view, all of my three solutions look pretty bad. It does not feel okay to do so many calls to the database? Store your entire website text in a file? Parse HTML with regexps?
What are the usual approaches used to solve this problem?
There's a great book out there: Crafting Rails 4 Applications. Here's the link to source code from the book. You will find example in templater folder. Basically, you will be able to create custom templates based on the request parameters (just like Rails does).
Update. Here's a couple of links:
Default views in Rails 3.0 with custom resolvers by José Valim (author of the book, by the way).
Implementing a Rails 3 View Resolver.
Also, here's 5 coins from me. Basically, it works like this. You need to define your own resolver and connect it to your ApplicationController (or any other controller you want):
class Resolver < ActionView::Resolver
# some code here
end
class ApplicationController < ActionController::Base
append_view_path Resolver.new
end
During the rendering process, Rails will ask your controller's resolvers to provide a template (it will go through each of them, until it finds template or until there won't be any resolvers left). In order to provide template, your resolver needs a find_templates method:
def def find_templates(name, prefix, partial, details)
# some processing here
end
So, based on this method parameters, you're going to provide some database records. But even if you have some kind of model already, Rails expects this method to return ActionView::Template instance. It can be initialized like this:
ActionView::Template.new(source, identifier, handler, details)
So, that's how your find_templates should look like:
def find_templates(name, prefix, partial, details)
template = DatabaseTemplate.find... # your custom model for DB templates
ActionView::Template.new... # initializing actual template
end
Both model and resolver in detail are presented in the book's source code (templater/3_final/app/models/sql_template.rb).
I have done that a couple times with awesome user satisfaction by using this:
http://jejacks0n.github.io/mercury/
There is also a Railscast available which gives you a good overview and step by step instructions:
http://railscasts.com/episodes/296-mercury-editor
Hope it helps. It looks good and is easy to use for end users.
So lets say I have a form for submitting a new post.
The form has a hidden field which specify's the category_id. We are also on the show view for that very category.
What I'm worried about, is that someone using something like firebug, might just edit the category id in the code, and then submit the form - creating a post for a different category.
Obviously my form is more complicated and a different scenario - but the idea is the same. I also cannot define the category in the post's create controller, as the category will be different on each show view...
Any solutions?
EDIT:
Here is a better question - is it possible to grab the Category id in the create controller for the post, if its not in a hidden field?
Does your site have the concept of permissions / access control lists on the categories themselves? If the user would have access to the other category, then I'd say there's no worry here since there's nothing stopping them from going to that other category and doing the same.
If your categories are restricted in some manner, then I'd suggest nesting your Post under a category (nested resource routes) and do a before_filter to ensure you're granted access to the appropriate category.
config/routes.rb
resources :categories do
resources :posts
end
app/controllers/posts_controller
before_filter :ensure_category_access
def create
#post = #category.posts.new(params[:post])
...
end
private
def ensure_category_access
#category = Category.find(params[:category_id])
# do whatever you need to do. if you don't have to validate access, then I'm not sure I'd worry about this.
# If the user wants to change their category in their post instead of
# going to the other category and posting there, I don't think I see a concern?
end
URL would look like
GET
/categories/1/posts/new
POST
/categories/1/posts
pst is right- never trust the user. Double-check the value sent via the view in your controller and, if it does't match something valid, kick the user out (auto-logout) and send the admin an email. You may also want to lock the user's account if it keeps happening.
Never, ever trust the user, of course ;-)
Now, that being said, it is possible to with a very high degree of confidence rely on hidden fields for temporal storage/staging (although this can generally also be handled entirely on the server with the session as well): ASP.NET follows this model and it has proven to be very secure against tampering if used correctly -- so what's the secret?
Hash validation aka MAC (Message Authentication Code). The ASP.NET MAC and usage is discussed briefly this article. In short the MAC is a hash of the form data (built using a server -- and perhaps session -- secret key) which is embedded in the form as a hidden field. When the form submission occurs this MAC is re-calculated from the data and then compared with the original MAC. Because the secrets are known only to the server it is not (realistically) possible for a client to generate a valid MAC from the data itself.
However, I do not use RoR or know what modules, if any, may implement security like this. I do hope that someone can provide more insight (in their own answer ;-) if such solutions exist, because it is a very powerful construct and easily allows safe per-form data association and validation.
Happy coding.